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

Почему константы массива могут использоваться только в инициализаторах?

Возможный дубликат:
Константы массивов могут использоваться только при ошибке инициализаций

Я изучал массивы, и я прошел через этот короткий метод объявления и инициализации массива в одной строке. Например,

int[] a = {1, 2, 3, 4, 5};

Но когда я попытался выполнить следующий код, я получил эту ошибку компилятора: "Константы массива могут использоваться только в инициализаторе".

int[] a;
a = {1, 2, 3, 4};

Почему так?

4b9b3361

Ответ 1

Это не разрешено, потому что JLS говорит так. Синтаксис разрешен только в объявлениях и выражениях создания массива.

Последние предоставляют альтернативный способ достижения такого же результата:

int[] a;
a = new int[]{1, 2, 3, 4};

Что касается фактической основной причины, требующей new T[], я предполагаю следующее. Рассмотрим следующий инициализатор массива:

{1, 2, 3, 4}

Его можно использовать для инициализации массивов разных типов:

new int[]{1, 2, 3, 4};
new float[]{1, 2, 3, 4};
new double[]{1, 2, 3, 4};

Если бит new T[] не требовался, я подозреваю, что голый {1, 2, 3, 4} может вызвать трудности при семантическом анализе. Здесь я думаю о таких случаях, как:

void f(float[] x) { ... }
void f(double[] x) { ... }
void g() {
  f({1, 2, 3, 4});
}

Если этот синтаксис разрешен, спецификация языка должна иметь дело со сложностью выбора функции, которую вызывать.

В подобном ключе не понятно, какой должен быть тип {null}. Это может быть Object[], Integer[], Serializable[] и т.д.

И, наконец, пустой массив {} был бы самым сложным из всех. Здесь мы даже не можем сказать, массив массивов или массив скаляров.

Вместо того, чтобы справляться со всеми этими сложностями, кажется, что разработчики языка решили избежать их, требуя синтаксиса new T[].

Ответ 2

Короткий ответ потому что спецификация языка говорит так.

Почему? Я подозреваю, что это печатать. В первом случае анализатор/компилятор знает об этом в контексте инициализации переменной массива, и поэтому фигурные скобки могут быть выведены как инициализатор массива.

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

Этот аргумент, похоже, имеет вес, потому что вы можете использовать очень похожий синтаксис, если вы специально (и технически избыточно) снова объявляете тип:

int[] a;
// then later
a = new int[] { 1, 2, 3, 4 };

Ответ 3

I java вы можете только инициализировать массив, используя первый метод. Вы не можете назначить массив. Понимание того, почему может потребоваться какая-то теория о том, как массивы реализуются. Компилятор должен знать, как большой массив, когда массив объявлен так с объявлением и инициализацией в первой строке, компилятор может вывести размер, но не второй.

Ответ 4

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