为什么Java更喜欢调用双构造函数?

roc*_*ing 13 java constructor

public class test {
    test(double[] a)
    {
        System.out.println("in double");
    }
    test(Object a)
    {
        System.out.println("in object");
    }
    public static void main(String args[])
    {
        new test(null);
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我传递null了构造函数参数.由于null可以是任何东西,上面的代码编译罚款.当我运行代码时,我希望它在对象中打印,但它以double形式打印 这背后的原因是什么?

注意链接的问题可能不重复,因为此问题与原始数据类型与对象相关

rge*_*man 21

原因是Java解释null为任何类型,并且在选择要调用的方法时,它将选择首先参数类型的最具体的方法.因为null可以是类型double[]而a double[]Object,编译器会选择采用a的方法double[].如果选择参与同样可能尚未无关的类型,例如double[]String,那么编译器将无法选择的方法,这将导致不明确的方法调用错误.

JLS,第4.1节,规定:

空引用始终可以分配或转换为任何引用类型(第5.2节,第5.3节,第5.5节).

实际上,程序员可以忽略null类型,只是假装null只是一个可以是任何引用类型的特殊文字.

  • @rocking实际上,[`double []`与`Object`]相关(https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.10.3) . (4认同)

Jon*_*eet 9

这两个构造函数都适用,因为null可以转换为两个Objectdouble[]-所以编译器需要使用重载分析来确定调用哪个构造函数.

JLS 15.9.3使用JLS 15.12.2确定的"最具体的"构造函数签名的使用,在此基础上构造了最具体的参数类型,根据JLS 15.12.2.5.确切的细节有点模糊(IMO),但在这种情况下,基本的经验法则是"如果你可以从T1转换为T2,而不是T2转换为T1,那么T1更具体"就足够了.

double[]是一个更具体的类型比Object,因为有从隐式转换double[]Object,而不是相反.

  • @rocking:我给了你一个经验法则和规范链接......我不确定你还想要什么. (2认同)