Java 方法重载并选择最特定的类型
示例代码是:Java 方法重载并选择最特定的类型,java,static-methods,overloading,Java,Static Methods,Overloading,示例代码是: 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 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);
}
输出为:
调用的字符串10%2==0为真
被调用的对象
调用的字符串
对
test(null)
的第一次调用调用带有String
参数的方法,根据Java语言规范
这是可以理解的
1) 有人能解释一下在前面的调用中调用test()
的依据是什么吗
2) 同样,当我们放置时,说一个if
条件:
if(10%2==0){
test(null);
}
else
{
test(new Object());
}
它总是使用String
参数调用方法
编译器会在编译时计算表达式
(10%2)
?我想知道表达式是在编译时还是在运行时计算的。谢谢。我认为你的问题在于你做出了错误的假设,你的表达方式:
test((10%2==0)?null:new Object());
(10%2==0)? null : new Object(); // A
(10%2==0)? null : null; // B
及
将始终调用test(null),这就是它们将通过test(Object)的原因
同:
Object o;
if(10%2==0)
o=null;
else
o=new Object();
test(o);
由于
o
的类型是Object
(就像(10%2==0)的类型一样),因此将始终调用null:newobject()
)测试(Object)
。o
的值无关紧要。您的答案是:运行时,因为在运行时指定参数是否为字符串的实例,所以在编译时无法找到它。正如@Banthar提到的结束?:
操作符首先为变量赋值,然后计算条件。
另一方面,您提到的if
条件总是返回true,因此编译器将仅用if
1)if1)的test()
方法由编译时的参数类型决定:
test((Object) null);
test((Object)"String");
输出:
Object called
Object called
2) 编译器更加智能,编译后的代码相当于:
test(null);
您可以使用javap-c
检查字节码:
0: aconst_null
1: invokestatic #6 // Method test:(Ljava/lang/String;)V
4: return
这就是我们对这个问题的看法
如果有多个方法声明可访问且适用
对于方法调用,必须选择一个来提供
运行时方法分派的描述符。Java编程
语言使用的规则是选择最具体的方法
这是您案例中的测试(字符串)方法
正因为如此,如果你加上
public static void test(Integer obj){
System.out.println("Ingeter called");
}
它将显示编译错误-类型重载测试的方法测试(字符串)不明确
正如JLS所说:
可能没有最具体的方法,因为有
两个或多个最大特定方法。在这种情况下:
如果所有最大特定方法具有相同的签名,则:
如果其中一个最大特定的方法未声明为抽象,则
这是最具体的方法。否则,所有的
方法必须声明为抽象的。最具体的方法是
在最大特定的方法中任意选择。但是,
大多数特定的方法被认为是在以下情况下引发选中的异常:
仅当在每个
最大特定方法。否则,我们说该方法
调用不明确,会发生编译时错误
Java使用早期绑定。最具体的方法是在编译时选择的。根据参数数量和参数类型选择最具体的方法。在这种情况下,参数的数量不相关。这就给我们留下了参数的类型 参数有什么类型?这两个参数都是表达式,使用三元条件运算符。问题归结为:条件三元运算符返回什么类型?类型是在编译时计算的 给出了两个表达式:
test((10%2==0)?null:new Object());
(10%2==0)? null : new Object(); // A
(10%2==0)? null : null; // B
列出了类型评估的规则。在B
中很容易,两个术语完全相同:null
将被返回()(JLS:“如果第二个和第三个操作数具有相同的类型(可能是null类型),那么这就是条件表达式的类型。”)。在A
中,第二个术语来自特定类别。由于这更为具体,并且null
可以替代类object
的对象,因此整个表达式的类型为object
(JLS:“如果第二个和第三个操作数中的一个为null类型,另一个为引用类型,则条件表达式的类型为该引用类型。”)
表达式的类型求值后,方法选择与预期一样
使用if
给出的示例是不同的:使用两种不同类型的对象调用方法。三元条件运算符在编译时总是计算为一种类型,适合这两个术语。JLS 15.25:
条件表达式的类型确定如下:
[……]
- 如果第二个和第三个操作数中的一个为null类型,而另一个为null类型 是引用类型,则条件表达式的类型就是该引用 类型
10 % 2 == 0 ? null : new Object();
这是一个很好的问题 让我试着澄清一下你上面写的代码
- 在第一个方法调用中
null
将转换为字符串类型,因此根据JLS调用测试(字符串obj)
- 在第二个方法调用中
新对象()
选项的最佳匹配。该方法以对象作为参数调用,因此它调用followin