Varargs Java不明确调用
我对Java的varargs方法有点困惑: 当我试图在不传递任何参数的情况下调用Varargs Java不明确调用,java,methods,overloading,variadic-functions,Java,Methods,Overloading,Variadic Functions,我对Java的varargs方法有点困惑: 当我试图在不传递任何参数的情况下调用sum()时,调用了方法的int版本。我不明白为什么;通常,编译器必须引发错误 相反,当我尝试在没有任何参数的情况下调用sum时,以下代码段会生成编译器错误: public static int sum(int ...a) { return 0; } public static boolean sum(boolean ...a) { return true; } 这里应用的一般规则是:如果一个方法
sum()
时,调用了方法的int
版本。我不明白为什么;通常,编译器必须引发错误
相反,当我尝试在没有任何参数的情况下调用sum
时,以下代码段会生成编译器错误:
public static int sum(int ...a) {
return 0;
}
public static boolean sum(boolean ...a) {
return true;
}
这里应用的一般规则是:如果一个方法签名严格地比另一个更具体,那么Java选择它时不会出错 直观地说,如果可以完全删除方法签名,则该方法签名更具体,而另一个不太具体的方法签名则适用于每个现有调用 当在签名
sum(int…args)
和sum(double…args)
之间进行选择时,签名sum(int…args)
更具体,因为该方法的任何调用也可以通过应用加宽转换传递给sum(double…args)
。对于不能进行类似转换的sum(boolean…args)
方法,情况并非如此
Java语言规范,SE 8版本:
15.12. 方法调用表达式
Java编程语言使用的规则是选择最具体的方法
对于参数表达式e1、…、ek的调用,如果以下任一项为真,则一个适用方法m1比另一个适用方法m2更具体:
- m2不是泛型的,m1和m2通过严格或松散调用适用,其中m1具有形式参数类型S1,…,Sn,m2具有形式参数类型T1,…,Tn,对于所有i(1)的参数ei,类型Si比Ti更具体≤ 我≤ n、 n=k)
int
由一个非十进制数(例如1
)表示,double
由一个十进制数表示,其精度比float
(例如1.0
)高32字节,因此我们可以说int
s“小于”或“小于”double
s,并且根据该逻辑,int
s可以“升级”到double
s,而double
s可以“降级”到int
s
简单地说,可以扩展到另一个原语的原语(例如,int
->float
->double
)比另一个原语更具体。例如,int
比double
更具体,因为1
可以升级为1.0
当您没有向这些同名的重载vararg方法传递任何参数时,由于返回值实际上是相同的(分别为0和0.0),编译器将选择使用接受类型为int
的vararg的方法,因为它更具体
因此,当您分别引入int
s和boolean
s(不能相互加宽的类型)的相同方法时,编译器现在无法选择要使用的方法,因为int
s不能像int
s、float
s和double
s那样“升级”或“降级”。因此,它将抛出编译错误
我希望这有助于你理解发生了什么。有趣的问题。你可能会找到你问题的答案。你似乎把
double
和float
搞混了。JLS 8的第5.1.2节将float
调用为double
19个“加宽原语转换”中的一个。您的回答意味着double
可以扩展为float
。
public static int sum(int ...a) {
return 0;
}
public static boolean sum(boolean ...a) {
return true;
}