示例代码是:
public class OverloadingTest {
public static void test(Object obj){
System.out.println("Object called");
}
public static void test(String obj){
System.out.println("String called");
}
public static void main(String[] args){
test(null);
System.out.println("10%2==0 is "+(10%2==0));
test((10%2==0)?null:new Object());
test((10%2==0)?null:null);
}
输出是:
String called
10%2==0 is true
Object called
String called
第一次调用 test(null)
会使用 String
参数调用该方法,这根据 Java 语言规范
是可以理解的。
1) 谁能解释一下在前面的调用中调用 test()
的依据是什么?
2) 当我们输入 时,再说一次 if
条件:
if(10%2==0){
test(null);
}
else
{
test(new Object());
}
它总是使用 String
参数调用该方法。
编译器在编译时会计算表达式(10%2)
吗?我想知道表达式是在编译时还是运行时计算的。谢谢。
最佳答案
Java 使用早期绑定(bind)。最具体的方法是在编译时选择的。最具体的方法是根据参数的数量和参数的类型来选择的。在这种情况下,参数的数量不相关。这给我们留下了参数的类型。
参数有什么类型?两个参数都是表达式,使用三元条件运算符。问题归结为:条件三元运算符返回什么类型?类型是在编译时计算的。
给出两个表达式:
(10%2==0)? null : new Object(); // A
(10%2==0)? null : null; // B
列出类型评估的规则here 。在 B
中很简单,两个术语完全相同:将返回 null
( whatever type that may be ) (JLS:“如果第二个和第三个操作数具有相同的类型(可能是 null 类型),那么这就是条件表达式的类型。”)。在 A
中,第二项来自特定类。由于这更具体,并且 null
可以替换 Object
类的对象,因此整个表达式的类型为 Object
(JLS:“如果第二个和第三个操作数之一为 null 类型,而另一个的类型为引用类型,则条件表达式的类型就是该引用类型。”)。
对表达式进行类型评估后,方法选择符合预期。
您给出的 if
示例有所不同:您使用两种不同类型的对象调用方法。三元条件运算符始终在编译时评估为符合这两个条件的一个类型。
关于java - 方法重载并选择最具体的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41238670/