为什么Java禁止数组初始值设定项作为方法调用参数?

为什么Java禁止数组初始值设定项作为方法调用参数?,java,jls,Java,Jls,在Java中,我们可以定义一个数组变量并按如下方式初始化它: int[]prime10=新的int[]{2,3,5,7}; 在JLS中,分配的右侧称为。JLS语法术语中的初始值设定项为 与所有表达式一样,ArrayCreationExpression可以在方法调用参数列表中使用: callMe(新的int[]{2,3,5,7}); 但是,我们也可以使用较短形式的,仅使用ArrayInitializer: int[]prime10={2,3,5,7}; 但是我们不能在一个函数中使用相同的初始

在Java中,我们可以定义一个数组变量并按如下方式初始化它:

int[]prime10=新的int[]{2,3,5,7};
在JLS中,分配的右侧称为。JLS语法术语中的初始值设定项为

与所有表达式一样,
ArrayCreationExpression
可以在方法调用参数列表中使用:

callMe(新的int[]{2,3,5,7});
但是,我们也可以使用较短形式的,仅使用
ArrayInitializer

int[]prime10={2,3,5,7};
但是我们不能在一个函数中使用相同的初始值设定项

//在JAVA中是非法的
callMe({2,3,5,7});
当然,在分析语法时,编译失败的原因是可以理解的——摘自JLS:

VariableDeclarator:
  VariableDeclaratorId [= VariableInitializer]

VariableInitializer:
  Expression 
  ArrayInitializer

MethodInvocation:
  MethodName ( [ArgumentList] )
  // plus other variants...

ArgumentList:
  Expression {, Expression}
但为何要作出这样的决定呢?为什么不让
ArrayInitializer
成为
表达式
,或者至少在
参数列表中添加一个带有
ArrayInitializer
的变量?这是明显的句法上的,还是有其他原因(可能是类型推断)禁止这种扩展

更新

在本着“您如何知道
{1,2,3}
的类型”的精神进行了一些评论之后,进行了技术澄清

在方法调用中,方法形式参数决定允许的参数类型。因此,如果我有一个方法声明:

void callMe(数字[]数字){
//...
}
然后被询问的电话

callMe({1,2,3});//在爪哇仍然是非法的
意味着

callMe(新号码[]{1,2,3});

所以这里没问题。我的问题不是针对固执己见的“谁需要这个”——谁需要羔羊肉、钻石和
var
反正;)-但是,从JLS的角度,或者至少从“Java架构师”将这些特性引入语言的角度来看,是什么(正式地)禁止了这样的构造?

什么是
{2,3,5,7}
的数组类型

字节[]???短[]???字符[]???长[]


如果有明确的说明,它就在那里。如果它是使用为它决定的任何规则来推断的,那么对于开发人员来说,这又是一个需要学习的规则


(PS在变量初始值设定项中,它可以从变量的类型声明中推断出来。在方法调用中,它不能从方法签名中推断出来,因为方法绑定的工作方式正好相反:必须首先知道参数类型,因为它们是决定所涉及的方法的决定性因素。)做出这样的决定是可以理解的。你建议用什么样的规则来推断{1,2,3}或{1,“dasqwe”,“c'}等的类型?创建的问题比解决的问题多。

“这是开发人员需要学习的另一个规则”当您考虑Java 10之后添加到Java中的其他推理规则(如菱形运算符或
val
)时,此参数非常弱。所以“新规则”对Java维护者来说不是问题。现在Java不再那么受欢迎了,但我确实认为很多人已经被val带来的“舒适感”的另一面所困扰。如果人们对新规则有问题或者没有问题,现在其实并不重要,重要的是,如果Java架构师选择不实现新特性,因为它意味着新规则。添加其他内容(如菱形运算符或
val
)表明新规则似乎没有那么重要。因此,单凭这一点并不是它还没有实施的原因;调用方法时,方法声明的形式参数告诉编译器所需的类型。因此,数组的组件类型将由方法声明决定。至于
{1,“dasqwe”,“c'}
,只要您知道组件类型(如上所述,通过形式参数),例如
Number[]b={1,1.2,new BigDecimal(“1.200000000001”)
就不会有问题。