2013-10-14 45 views

回答

7

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将回暖,如果它的固定元数法能够。

+1

非常明确的解释,谢谢。 – ajb

0

我同意你的肖恩,下面的代码可以调用任何你定义的两个构造函数:

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()); 

我希望帮助解释,为什么你不不要让编译器抱怨它(这只是他们认为它应该工作的方式)。

相关问题