public class NullDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
NullDemo n = new NullDemo();
n.execute(null);
}
public void execute(Object o) {
System.out.println("object");
}
public void execute(Double o) {
System.out.println("double");
}
}
我执行了上面这段代码并用execute(Double o)执行方法。我需要知道它执行execute(Double o)和不执行(Object o)的原因
并假设
public class NullDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
NullDemo n = new NullDemo();
n.method1(null); /// give the compilation error
}
public void method1(Float o) {
System.out.println("object");
}
public void method1(Double o) {
System.out.println("double");
}
}
如果我使方法public void method1(Float o)和public void method1(Double o)它会给出编译错误,为什么会这样?这与层次结构有关吗?
答案 0 :(得分:1)
Java更愿意调用继承树最下面的方法。请考虑以下情况:
class Demo {
public void doSomething(ParentClass foo) {
//.....
}
public void doSomething(ChildClass foo) {
//.....
}
public static void main() {
Demo demo = new Demo();
demo.doSomething(new ChildClass());
}
}
在上面的情况中,方法调用可以匹配两种方法中的任何一种。但是,您可以直观地看到它应该与第二种方法匹配。
您可以阅读java规范中的确切行为: http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2
答案 1 :(得分:0)
根据您的初始代码,向(Object)
添加转换将打印出您期望的内容。这是因为Double
是more specific然后是Object
,因此默认调用它,
public static void main(String[] args) {
NullDemo n = new NullDemo();
n.execute((Object) null);
}
public void execute(Object o) {
System.out.println("object");
}
public void execute(Double o) {
System.out.println("double");
}
答案 2 :(得分:0)
如果两个或多个方法可适用于方法调用,则编译器将选择更具体的方法(如果可能)。在第一个示例中,方法execute(Double o)
更具体,因为Double
是Object
的子类。在第二个示例中,两个方法都不具体,因为Double
和Float
都不是另一个的子类。由于两种方法都适用(null
可以作为Double
或Float
),并且两者都不具体,因此编译器报告该调用不明确。