Java 不明确的varargs方法
下面是一个未编译的代码示例:Java 不明确的varargs方法,java,methods,variadic-functions,Java,Methods,Variadic Functions,下面是一个未编译的代码示例: public class Test { public static void main(String[] args) { method(1); } public static void method(int... x) { System.out.println("varargs"); } public static void method(Integer... x) { Sy
public class Test {
public static void main(String[] args) {
method(1);
}
public static void method(int... x) {
System.out.println("varargs");
}
public static void method(Integer... x) {
System.out.println("single");
}
}
有人能告诉我这些方法不明确的原因吗?提前感谢。int和Integer之间的区别在于Integer是一种对象类型。您可以在查找int类型的最大数目或与Integer进行比较等情况下使用 整数对象已与比较方法等方法关联:
public static void method(int x, int y) {
System.out.println(Integer.compare(x, y));
}
查看更多信息:int和Integer之间的区别在于Integer是一种对象类型。您可以在查找int类型的最大数量或与Integer进行比较等情况下使用 整数对象已与比较方法等方法关联:
public static void method(int x, int y) {
System.out.println(Integer.compare(x, y));
}
更多信息请访问:,因为它们模棱两可。根据JLS,您可以进行加宽、装箱或装箱然后加宽。在您的示例中,有两个方法参数可以相互装箱/取消装箱。在编译时,由于varargs的缘故,是不可见的,而在java中,varargs总是不是绝对清晰的
即使Sun建议开发人员不要重载varargs方法,编译器中也存在与之相关的bug()。因为它们不明确。根据JLS,您可以进行加宽、装箱或装箱然后加宽。在您的示例中,有两个方法参数可以相互装箱/取消装箱。在编译时,由于varargs的缘故,是不可见的,而在java中,varargs总是不是绝对清晰的
即使Sun建议开发人员不要重载varargs方法,编译器中也存在与之相关的bug()。考虑方法签名
public static void foo(int a)
及
在装箱和取消装箱之前,调用foo(1)
不会有歧义。为了确保与早期版本的Java兼容,调用仍然是明确的。因此,重载解析的第一阶段不允许同时引入装箱、取消装箱或变量arity调用。变量arity调用是指通过为最后一个参数(而不是数组)传递一系列参数来调用varargs方法
但是,方法签名的方法(1)
解析允许装箱和取消装箱,因为这两种方法都需要变量arity调用。由于允许装箱,所以两个签名都适用。通常,当应用两个重载时,会选择最具体的重载。但是,两个签名都不比另一个更具体(因为int
和Integer
都不是另一个的子类型)。因此,调用方法(1)
是不明确的
您可以通过传递
newint[]{1}
来进行编译。考虑方法签名
public static void foo(int a)
及
在装箱和取消装箱之前,调用foo(1)
不会有歧义。为了确保与早期版本的Java兼容,调用仍然是明确的。因此,重载解析的第一阶段不允许同时引入装箱、取消装箱或变量arity调用。变量arity调用是指通过为最后一个参数(而不是数组)传递一系列参数来调用varargs方法
但是,方法签名的方法(1)
解析允许装箱和取消装箱,因为这两种方法都需要变量arity调用。由于允许装箱,所以两个签名都适用。通常,当应用两个重载时,会选择最具体的重载。但是,两个签名都不比另一个更具体(因为int
和Integer
都不是另一个的子类型)。因此,调用方法(1)
是不明确的
您可以通过传递
newint[]{1}
来进行编译。重载解析()中使用了三个阶段:
方法(1)
时选择其中一种方法,t