我有两个编译得很好的构造函数,但我希望Java抱怨模糊性的可能性。变量参数构造函数_可能会发生冲突,但编译
public Foo(int id, Bar bar, String name, String description){
}
public Foo(int id, Bar bar, String... values){
}
什么给了?
我有两个编译得很好的构造函数,但我希望Java抱怨模糊性的可能性。变量参数构造函数_可能会发生冲突,但编译
public Foo(int id, Bar bar, String name, String description){
}
public Foo(int id, Bar bar, String... values){
}
什么给了?
Java允许这些方法存在,因为它具有关于如果两者都适用时将调用哪一个的规则。具体而言,将通过变量arity方法(使用...
)选择固定方法(不包括...
)。
第一阶段(§15.12.2.2)执行过载分辨率而不 允许拳击或取消装箱转换,或使用可变元数 的:
JLS, Section 15.12.2的,确定选择哪种方法,当指出以下方法调用。如果在此阶段没有找到适用的方法 ,则处理继续到第二阶段。
这保证了该是有效的在Java SE 5.0之前的Java编程语言 任何电话不被认为模棱两可的结果引进的变量元数法,隐式装箱和/或 拆箱的 。但是,变量数组方法(§8.4.1) 的声明可以更改为给定方法方法调用 表达式选择的方法,因为在第一阶段中将变量数组方法视为固定的方法。例如,在一个已经声明m(Object)的类中声明m(Object ...) 可以使m(Object)更长地被选择用于某些调用表达式(例如m(null)),作为 m对象[])更具体。
第二阶段(§15.12.2.3)执行重载解析而 允许装箱和拆箱,但仍排除使用可变 元数的方法调用的。如果在 阶段没有找到适用的方法,则处理继续到第三阶段。
这确保如果方法调用适用于通过固定方法调用 调用,方法调用将不会通过变量参数 选择方法。
第三阶段(§15.12.2.4)允许将超载与 可变阵列方法,装箱和拆箱相结合。
(重点煤矿)
示例代码:
class Bar{}
public class Foo{
public static void main (String [] args){
Foo main = new Foo(1, new Bar(), "name", "description");
Foo main2 = new Foo(2, new Bar(), "name");
Foo main3 = new Foo(3, new Bar(), "name", "description", "otherValues");
Foo main4 = new Foo(4, new Bar());
}
public Foo(int id, Bar bar, String name, String description) {
System.out.println("name and description!");
}
public Foo(int id, Bar bar, String... values) {
System.out.println("values!");
}
}
此打印出:
name and description!
values!
values!
values!
...表明Java将回暖,如果它的固定元数法能够。
非常明确的解释,谢谢。 – ajb
我同意你的肖恩,下面的代码可以调用任何你定义的两个构造函数:
Foo foo = new Foo(3, new Bar(), "", "");
然而,当Java人们推出了“可变参数符号”,他们决定,上述将称为“最特殊的构造函数”。在这种情况下,我有2个字符串参数,你的第一个构造函数需要2个字符串参数,所以它会被调用。
第二个构造函数只被调用,如果有多于或少于2个字符串参数,例如:
Foo foo = new Foo(3, new Bar(), "", "", "");
甚至:
Foo foo = new Foo(3, new Bar());
我希望帮助解释,为什么你不不要让编译器抱怨它(这只是他们认为它应该工作的方式)。
+1好问题。起初,我误解了你的问题。 –