在下面的代码中,输出是
字符串
如果我使用String
类型的参数删除方法,则输出为
对象
我知道当参数类型不完全匹配时方法的重载如何起作用但我无法理解 null 如何被视为Object
和/或{{1参数。
对此有何解释?
String
答案 0 :(得分:16)
它总是根据Java specs第15.12.2.5节使用最具体的方法。
介绍对此有合理的说明:
如果多个成员方法都可访问并适用于方法调用,则必须选择一个为运行时方法调度提供描述符。 Java编程语言使用选择最具体方法的规则。
非正式的直觉是,如果第一个方法处理的任何调用都可以传递给另一个没有编译时类型错误的调用,那么一个方法比另一个方法更具体。
一般来说,至少在代码可读性方面,最好尽量做到尽可能明确。您可以将null
转换为与您要调用的签名匹配的类型。但这绝对是一个值得怀疑的做法。它假定每个人都知道这个规则,并使代码更难以阅读。
但这是一个很好的学术问题,所以我给你的问题+1。
答案 1 :(得分:8)
当多个重载符合签名时,Java会从中选择最具体的方法。
null
的值与Object
和String
都匹配,但String
是Object
的子类,因此选择了String
。如果在类层次结构中添加另一个带有String
兄弟的重载,则会出现编译错误。\
// DOES NOT COMPILE
class C {
static void m1(Object x) {
System.out.print("Object");
}
static void m1(String x) {
System.out.print("String");
}
static void m1(Integer x) {
System.out.print("Integer");
}
public static void main(String[] args) {
m1(null);
}
}
这是link to a post,它会详细讨论您的代码示例。
答案 2 :(得分:5)
如果在将null
作为参数传递时需要强制调用某个重载方法,则必须将其强制转换,如下所示:
m1((String)null);
通过执行此操作,您可以确保调用方法的正确重载版本。
答案 3 :(得分:2)
您必须设置null
的类型以告诉Java您要调用哪个函数。
所以你这样做:m1((Object) null);
使用Object
参数调用实现,然后m1((String) null);
调用另一个参数。
答案 4 :(得分:1)
1。由于字符串也是一个对象,JVM
得到混淆来调用运行时< /强>
2. 如果要指定在运行时调用哪种方法,可以通过显式强制转换
来执行此操作<强>例如强>
m1((String)null);