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);
}
}
在上面的代码中,我传递null
作为构造函数参数。由于null
可以是任何东西,上面的代码编译得很好。当我运行代码时,我希望它在对象中打印,但它会在中打印
这背后的原因是什么?
注意链接的问题可能不重复,因为此问题与原始数据类型与对象相关
答案 0 :(得分:21)
原因是Java将null
解释为任何类型,并且在选择要调用的方法时,它将选择首先参数类型的最具体方法。由于null
可以是double[]
类型而double[]
是Object
,因此编译器将选择采用double[]
的方法。如果选择涉及同样可能但不相关的类型,例如double[]
和String
,然后编译器将无法选择方法,这将导致模糊的方法调用错误。
JLS, Section 4.1,声明:
可以始终为空引用赋值或转换为任何引用类型(第5.2节,第5.3节,第5.5节)。
在实践中,程序员可以忽略null类型,只是假装null只是一个可以是任何引用类型的特殊文字。
答案 1 :(得分:9)
两个构造函数都适用,因为null
可以转换为Object
和double[]
- 因此编译器需要使用重载决策来确定要调用的构造函数。
JLS 15.9.3使用JLS 15.12.2来确定要使用的“最具体”的构造函数签名,具体取决于哪个构造函数具有最具体的参数类型。确切的细节有点模糊(IMO),但在这种情况下,基本的经验法则是“如果你可以从T1转换为T2,而不是T2转换为T1,那么T1更具体”就足够了。
double[]
是一种比Object
更具体的类型,因为存在从double[]
到Object
的隐式转换,但反之亦然。