Подтвердить что ты не робот

Инициализация массива в java

Я заметил, что можно написать такой код, что совершенно нормально, между прочим:

int arrays[] = {1, 2, 3};
for (int n : arrays)
   System.out.println(n);

Но я не вижу, как это незаконно:

for (int n : {1, 2, 3})
   System.out.println(n);

С точки зрения писателя компилятора это не приводит к какой-либо двусмысленности, не так ли? Ожидается, что тип массива будет того же типа, что и элемент, объявленный ранее. Другими словами, n объявляется как int, поэтому массив должен быть int[]

4b9b3361

Ответ 1

Вам нужен этот синтаксис:

for(int n : new int[]{1, 2, 3})
   System.out.println(n);

Ответ 2

Из спецификации языка Java, §10.6 - Инициализаторы массива:

Инициализатор массива записывается как список, разделенный запятыми выражения, заключенные в фигурные скобки {и}.

Заключительная запятая может появиться после последнего выражения в массиве инициализатор и игнорируется.

Каждый инициализатор переменной должен быть совместим с назначением (п. 5.2) с тип компонента массива или ошибка времени компиляции.

Это ошибка времени компиляции, если тип компонента массива инициализировано не поддаётся подтверждению (§4.7).

Инициализатор массива является частью выражения создания массива, который определяет, что для успешной инициализации массива требуется одна из этих четырех форм:

ArrayCreationExpression:
    new PrimitiveType DimExprs Dimsopt
    new ClassOrInterfaceType DimExprs Dimsopt
    new PrimitiveType Dims ArrayInitializer 
    new ClassOrInterfaceType Dims ArrayInitializer

Опять же, из спецификаций:

Это ошибка времени компиляции, если класс ClassOrInterfaceType не обозначает повторно идентифицируемый тип (§4.7). В противном случае ClassOrInterfaceType может называть любой именованный ссылочный тип, даже абстрактный тип класса (§8.1.1.1) или тип интерфейса (§9).

Вот почему вам нужен синтаксис new int[] {1, 2, 3}.

EDIT. Чтобы узнать больше о нюансах вашего вопроса:

С точки зрения автора компилятора это не вводит никаких двусмысленность, не так ли? Ожидается, что тип массива будет тот же тип, что и элемент, объявленный ранее. Другими словами, n является объявленный как int, поэтому массив должен быть int []

Нет. Существует двусмысленность. Как для экземпляра, в чем разница между следующими двумя утверждениями?

int[] arr1 = new int[] {1, 2, 3};
short[] arr2 = new short[] {1, 2, 3};

Основное отличие заключается в том, что они скомпилируют в байт-коде. Один, очевидно, int, другой, очевидно, короткий. Однако без возможности указать, какой тип данных является (без значений в массиве, превышающем Short.MAX_VALUE), было бы невозможно утверждать, что этот массив, вне тени сомнения, является int. Напомним, что a short попадает в диапазон int, поэтому вы можете легко попасть в некоторые сложные/причудливые сценарии при использовании этого.

Это становится веселее: это допустимый код.

for(int i : arr2) {
    System.out.println(i);
}

Опять же, пока элементы в arr2 не превышают Short.MAX_VALUE, вы можете избежать этой неоднозначной ссылки между short и int.

Это еще одна причина, по которой компилятор не может просто заключить, что вы имеете в виду int. Вы могли бы означать short. *

*: Не то, чтобы многие люди когда-либо были, но это на всякий случай есть.

Ответ 3

Поскольку массивы являются объектами и должны быть созданы. Java не распознает {} сам по себе как массив. Тем не менее, он позволяет вам использовать блок кода (т.е. Код в {..}) для определения начальных элементов массива.

То, как вы это достигаете, описано выше.

Ответ 4

Я думаю, что всякий раз, когда мы создаем переменную, компилятор автоматически выделяет ей память. Объем создаваемой памяти зависит от типа используемого вами компилятора. В первом заявлении вы объявляете массив со входом, компилятор автоматически создает пространство для элемента массива, присутствующего в массиве, но когда вы объявляете массив в цикле, он создает только 2 байта каждого прогона.

Например,

int x; // create 2 bytes of memory

Это пространство постоянно выделяется для int x, вставляете ли вы значение в это пространство или нет.

int x = "123"; // This code also take 2 bytes of memory and contain value = 123

Аналогично,

int a[] ={1,2,3} // create 6 byte of space in memory, 2 byte for each integer variable.

С другой стороны, когда вы объявляете массив в цикле без использования нового идентификатора, компилятор предполагает, что он является переменной int и создает только 2 байта пространства памяти, и программа дает ошибку.

for (int n : {1, 2, 3}) // create only 2 bytes of memory

Таким образом, используя новый идентификатор, мы выделяем новое пространство памяти и вставляем значения, которые указываются в фигурных скобках.

Ответ 5

Честно говоря, единственное, что я вижу в вашем объяснении, - это то, как вы можете сказать компьютеру пройти через объект/память, которая не существует?

Вы должны создать что-то, чтобы сначала пройти через него, здесь вы ничего не создали, и логическая ошибка существует в вашей голове, потому что вы считаете, что это глубже, чем правила создания самой Java.

Не волнуйтесь, я нахожусь в таких ситуациях, как вы, но самое главное - узнать, как сначала была запрограммирована Java!