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

2022-09-04 06:49:05
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);
    }
}

在上面的代码中,我作为构造函数参数传递。与任何东西一样,上面的代码编译得很好。当我运行代码时,我期望它打印在对象中,但它以双倍打印 这背后的原因是什么?nullnull

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


答案 1

原因是Java解释为任何类型,并且在选择要调用的方法时,它将选择最具体的方法,首先是参数类型。因为可以是该类型,而 a 是一个,编译器将选择采用 .如果选择涉及同样可能但不相关的类型,例如 和 ,则编译器将无法选择方法,这将导致不明确的方法调用错误。nullnulldouble[]double[]Objectdouble[]double[]String

JLS 第 4.1 节规定:

始终可以将空引用赋值或强制转换为任何引用类型(§5.2、§5.3、§5.5)。

在实践中,程序员可以忽略 null 类型,而只是假装 null 只是一个可以属于任何引用类型的特殊文本。


答案 2

这两个构造函数都适用,因为可以同时转换为和 - 因此编译器需要使用重载解析来确定要调用哪个构造函数。nullObjectdouble[]

根据 JLS 15.12.2.5JLS 15.9.3 使用 JLS 15.12.2 来确定要使用的“最具体”构造函数签名,基于该构造函数具有最具体的参数类型。确切的细节略显晦涩难懂(IMO),但在这种情况下,“如果您可以从T1转换为T2,但不能从T2转换为T1,那么T1更具体”的基本经验法则就足够了。

double[]是比 更具体的类型,因为存在从 到 的隐式转换,但反之亦然。Objectdouble[]Object