В Java мы можем определить переменную массива и инициализировать ее следующим образом:
int[] prime10 = new int[] { 2, 3, 5, 7 };
В JLS правая часть присваивания называется ArrayCreationExpression
. Инициализатор в терминах синтаксиса JLS: ArrayInitializer
а>.
Как и все выражения, ArrayCreationExpression
можно использовать в списке аргументов вызова метода:
callMe(new int[] { 2, 3, 5, 7 });
Однако мы также можем использовать более короткую форму VariableInitializer
, только с ArrayInitializer
:
int[] prime10 = { 2, 3, 5, 7 };
но мы не можем использовать тот же инициализатор в вызов метода
// ILLEGAL IN JAVA
callMe({ 2, 3, 5, 7 });
Конечно, понятно, почему не получается компиляция, при анализе синтаксиса — выдержка из JLS:
VariableDeclarator:
VariableDeclaratorId [= VariableInitializer]
VariableInitializer:
Expression
ArrayInitializer
MethodInvocation:
MethodName ( [ArgumentList] )
// plus other variants...
ArgumentList:
Expression {, Expression}
но почему было принято такое решение? Почему бы не сделать ArrayInitializer
Expression
или хотя бы добавить вариант с ArrayInitializer
к ArgumentList
? Является ли это чисто синтаксическим или есть другие причины (возможно, вывод типа), которые запрещают такое расширение?
ОБНОВЛЕНИЕ
После некоторых замечаний в духе "откуда вы знаете тип {1, 2, 3}
", техническое уточнение.
При вызове метода формальные параметры метода определяют допустимые типы аргументов. Итак, если у меня есть объявление метода:
void callMe(Number[] numbers) {
//...
}
затем вопросительный звонок
callMe({ 1, 2, 3 }); // still ILLEGAL in Java
означало бы
callMe(new Number[] { 1, 2, 3 });
Так что здесь нет проблем. Мой вопрос не к самоуверенным "кому это нужно" - кому в любом случае нужны лямбда-выражения, бриллианты и var
;) - а скорее, что запрещает (формально) такую конструкцию с точки зрения JLS или, по крайней мере, с точки зрения " Java-архитекторы», вводящие такие функции в язык?