使用变量参数重载方法(varargs) [英] Method overloading with variable arguments (varargs)
问题描述
看到这段代码的输出,我感到很惊讶:
I am surprised by seeing the output of this code :
public class File
{
public static void main(String[] args)
{
movie();
}
static void movie(double... x)
{
System.out.println("No varargs");
}
static void movie(int... x)
{
System.out.println("One argument");
}
}
它输出,
One argument
为什么会这样?
我认为该代码无法编译,因为对movie()
的调用是 模糊 ,但它运行正常并输出One argument
.
I thought that this code would not compile because the call to movie()
is ambiguous, but it runs fine and outputs One argument
.
如果我将代码修改为:
public class File
{
public static void main(String[] args)
{
movie();
}
static void movie(boolean... x) //Changed the parameter type to boolean from double
{
System.out.println("No varargs");
}
static void movie(int... x)
{
System.out.println("One argument");
}
}
有错误消息.
为什么第一个代码可以正常运行,但是第二个却出现错误?
Why does the first code run fine, but the second gives an error?
推荐答案
此行为是由于int
比double
更具体,而int
和boolean
之间没有这样的比较.
This behaviour is due to the fact that int
is more specific than double
while there is no such comparison between int
and boolean
.
JLS中指定的第15.12.2.5节(重点是我的):
As specified in the JLS section 15.12.2.5 (emphasis mine):
对于具有参数表达式e1,...,ek的调用,如果满足以下任一条件,则一个适用的方法m1比另一个适用的方法m2 更具体:
- ...
- m2不是通用的, m1和m2可通过变量arity调用来应用,并且其中m1的前k个变量arity参数类型为S1,...,Sk和前k个变量m2的稀疏参数类型为T1,...,Tk,对于所有i(1≤i≤k)的自变量ei,Si的类型比Ti更具体.另外,如果m2具有k + 1个参数,则m1个第k + 1个可变稀疏参数类型是m2个第k + 1个可变稀疏参数类型的子类型.
- ...
- m2 is not generic, and m1 and m2 are applicable by variable arity invocation, and where the first k variable arity parameter types of m1 are S1, ..., Sk and the first k variable arity parameter types of m2 are T1, ..., Tk, the type Si is more specific than Ti for argument ei for all i (1 ≤ i ≤ k). Additionally, if m2 has k+1 parameters, then the k+1'th variable arity parameter type of m1 is a subtype of the k+1'th variable arity parameter type of m2.
更具体的的实际含义稍后用
对于任何表达式,如果S< ;: T,则类型S比类型T更具体.
A type S is more specific than a type T for any expression if S <: T. 这表示 This means that 请注意, 就这样 编译和 compiles and 但是, 之所以无法编译,是因为无法将 does not compile because 这篇关于使用变量参数重载方法(varargs)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
S
比T
更具体,因为S
是T
的子类型.对于原始类型,这归结为S
is more specific than T
is S
is a subtype of T
. For primitive types, this comes down to the following properties:
boolean
不存在.public static void main(String[] args) {
movie();
}
static void movie(int... x) { }
static void movie(short... x) { }
static void movie(double... x) { }
static void movie(byte... x) { }
movie(byte... x)
将被调用,因为它是最具体的.movie(byte... x)
will be called because it is the most specific.public static void main(String[] args) {
movie();
}
static void movie(int... x) { }
static void movie(boolean... x) { }
boolean
与int
进行比较.boolean
cannot be compared to int
.