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)这个事实并不重要。我希望下层选民能补充一些意见;)