В отличие от C, где вы можете динамически увеличивать размер массива, массивы в java фиксируются по длине. Почему Java разрешает массивы размером 0, затем?
String[] strings = new String[0];
В отличие от C, где вы можете динамически увеличивать размер массива, массивы в java фиксируются по длине. Почему Java разрешает массивы размером 0, затем?
String[] strings = new String[0];
Это означает, что он пуст. То есть вы можете зацикливаться на нем, как если бы у него были элементы и результата не было:
for(int k = 0; k < strings.length; k++){
// something
}
Таким образом, избегая необходимости проверки. Если рассматриваемый массив был null
, произойдет исключение, но в этом случае он просто ничего не делает, что может быть уместно.
Почему Java разрешает массивы размером 1? Разве не бесполезно обертывать одно значение в массив? Было бы недостаточно, если бы Java разрешала только массивы размером 2 или более?
Да, мы можем передать null
вместо пустого массива и одного объекта или примитива вместо матрицы размера один.
Но есть некоторые хорошие аргументы против такого ограничения. Мои личные главные аргументы:
Ограничение слишком сложное и не очень необходимое
Чтобы ограничить массивы размерами [1..INTEGER.MAX_INT], нам пришлось бы добавить много дополнительных контрольных проверок, (согласиться с комментарием Konrads), перевести логику и метод перегрузки в наш код, Исключение 0 (и, возможно, 1) из разрешенных размеров массива не экономит затраты, это требует дополнительных усилий и негативно влияет на производительность.
Матричный вектор моделей
Массив - хорошая модель данных для вектора (математика, а не класс Vector
!). И, конечно, вектор в математике может быть нулевым. Что концептуально отличается от несуществующего.
Sidenote - выдающаяся оболочка для массива (char -) - это класс String
. Неизменяемый String
реализует концепцию пустого массива: это пустая строка (""
).
Иногда гораздо удобнее возвращать массив нулевого размера, чем null.
Рассмотрим это (более подробное объяснение ответа на полдень):
public String[] getStrings() {
if( foo ) {
return null;
} else {
return new String[] {"bar, "baz"};
}
}
String[] strings = getStrings();
if (strings != null) {
for (String s : strings) {
blah(s);
}
}
Теперь сравните это с этим:
public String[] getStrings() {
if( foo ) {
return new String[0];
} else {
return new String[] {"bar, "baz"};
}
}
// the if block is not necessary anymore
String[] strings = getStrings();
for (String s : strings) {
blah(s);
}
Это (возврат пустых массивов, а не нулевые значения), на самом деле является лучшей практикой в мире разработки API Java.
Кроме того, в Java вы можете скрывать списки (например, ArrayList) в массивы, и имеет смысл преобразовать пустой список в пустой массив.
То же, что и С++, он позволяет обрабатывать более чистый, когда данных нет.
Другой случай, когда массив нулевой длины может быть полезен: Чтобы вернуть массив, содержащий все элементы в списке:
<T> T[ ] toArray(T[ ] a)
Массив нулевой длины может использоваться для передачи типа массива в этот метод. Например:
ClassA[ ] result = list.toArray(new ClassA[0]);
Массив с нулевой длиной все еще является экземпляром объекта, который содержит нулевые элементы.
В одном случае я могу думать о том, где пустой массив чрезвычайно полезен, - использовать его вместо нуля в ситуации, когда null не разрешен. Одним из возможных примеров этого является BlockingQueue массивов. Когда вы хотите сигнализировать о конце ввода на стороне чтения, что бы вы сделали? Отправка нулевого значения кажется очевидным выбором, но дело в том, что BlockingQueue не принимает значения null. Вы можете объединить свой массив внутри класса с полем "boolean last;
", но такого рода перебор. Отправка пустого (нулевого размера) массива кажется наиболее разумным выбором.
только примечание:
Вы говорите: "В отличие от C, где вы можете динамически увеличивать размер массива...", но в C вы не можете изменить размерность массива, то же самое для С++.