Java 了解选择哪一个构造函数及其原因

Java 了解选择哪一个构造函数及其原因,java,Java,为什么每次打印I'm string而不是I'm object.或I'm int.时都要执行以下程序 public class Demo { public Demo(String s){ System.out.println("I'm string"); } public Demo(int i){ System.out.println("I'm int."); } public Demo(Object o){

为什么每次打印
I'm string
而不是
I'm object.
I'm int.
时都要执行以下程序

public class Demo {

    public Demo(String s){
        System.out.println("I'm string");
    }

    public Demo(int i){
        System.out.println("I'm int.");
    }

    public Demo(Object o){
        System.out.println("I'm object.");
    }

    public static void main(String[] args) {
        new Demo(null);
    }
}

同样,如果我将
int
替换为
Integer
。它给出错误,因为构造函数演示(字符串)不明确。为什么?

null
可以转换为
对象
字符串
,但不能转换为
int
。因此,第二个构造函数已退出

在转换为
对象
或转换为
字符串
之间,转换为
字符串
更为具体,因此这就是所选择的

JLS描述了方法重载解析,我相信同样的方法也用于构造函数解析。描述如何选择最具体的方法(本例中为构造函数):

非正式的直觉是,如果第一个方法处理的任何调用都可以传递给另一个方法,而不会出现编译时类型错误,那么一个方法比另一个方法更具体


这是关于使用对象或字符串参数的构造函数调用的,由
new Demo(String)
处理的任何调用也可以传递到
new Demo(Object)
,而不会出现编译时类型错误,但反过来不是真的,因此
new Demo(String)
一个调用更具体。。。因此,由重载解析规则选择。

当您有类似于上述的构造函数或方法时,编译器通常会尝试找到最接近的匹配项并使用它


在这些情况下,认为
null
的方法是它作为所有类型的子类型(是的,严格来说这不是真的,但它为思考发生了什么提供了一个很好的平台)。因此,使用此规则,它比对象更适合字符串,因此这是执行的构造函数。

要回答第二个问题(因为Jon Skeet已经讨论了第一个问题),当您同时拥有
字符串
构造函数和
整数
构造函数时,编译器不知道
新演示(null)
中的
是什么意思:它可以是
字符串
整数


因为
字符串
不能转换为
整数
(反之亦然),编译器放弃并报告不明确的错误。这与当您没有
整数
构造函数时的
字符串
对象
选项形成对比。

编译器在您的第二个错误中提到了字符串构造函数:

The constructor Demo(String) is ambiguous.
这并不重要。这是因为接受字符串的构造函数是第一个声明的构造函数,因此编译器在其错误消息中使用它。更改为首先使用对象构造函数,您将获得:

The constructor Demo(Object) is ambiguous.
它试图说的是,接受整数的构造函数和对象之间存在歧义,因此您必须更具体,因为null可以应用于每个构造函数。Integer不是字符串,因此这两种类型不兼容。您需要更加具体,以便编译器可以绑定构造函数调用


请参阅@Jon Skeet answer,了解编译器在某些实例中而在其他实例中不引发错误的原因

只是检查一下,如果更改构造函数的顺序会发生什么。将
对象
放在
字符串
之前@。。。那我就不知道了。祝你好运@Oltarus——构造函数的变更单?这是Java,不是一些脚本语言。方法和构造函数顺序无关紧要(静态和动态初始化块是一个例外)。@Nick抱歉,我打扰了你;-)我不是有意要侮辱这种完美的语言。我猜这是一种反射,比如著名的“你试过把它关掉再打开吗?”这似乎很受欢迎,不管问题是什么。@Oltarus--lol,没什么大不了的,只是有人不得不指出这种方法中的缺陷w/JavaGreat答案很好--这也解释了为什么在做新的演示(null)时,Demo(整数)与Demo(字符串)冲突@尼克甚至不是
整数
而是
字节
大十进制
任何
对象
都是模糊的。非常感谢。从来都不知道调用方法时会发生这么多。@JonSkeet:“null”可以转换为“Object”或“String”,这能解释得更清楚一点吗please@HussainAkhtarWahid“Ghouri”:意思是
对象x=null
字符串y=null
都是有效的-基本上null引用是任何类类型的变量的有效值。我没有投反对票,但这可能是因为您暗示构造函数是根据它们声明的顺序选择的。事实并非如此,只是错误消息使用了此选项。你可能想澄清一下措辞,让它更清楚一点:)是的,我可以澄清一下-我不是说情况就是这样,我只是想说编译器提到的Demo(String)这个事实并不重要。我希望下层选民能补充一些意见;)