一尘不染

Java方法重载并选择最特定的类型

java

示例代码为:

    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参数的方法,根据可以理解The Java Language Specification

1)谁能解释我test()在先前的调用中是基于什么来调用的?

2)再说一次,说一个if条件:

    if(10%2==0){
        test(null);
    }
    else
    {
        test(new Object());
    }

它总是使用Stringarguments 调用方法。

编译器在编译时会计算表达式(10%2)吗?我想知道表达式是在编译时还是在运行时计算的。谢谢。


阅读 653

收藏
2020-03-13

共1个答案

一尘不染

Java使用早期绑定。在编译时选择最具体的方法。根据参数数量和参数类型选择最具体的方法。在这种情况下,参数数量无关紧要。这给我们留下了参数的类型。

参数有什么类型?两个参数都是使用三元条件运算符的表达式。问题简化为:条件三元运算符返回哪种类型?类型是在编译时计算的。

给出两个表达式:

(10%2==0)? null : new Object(); // A
(10%2==0)? null : null; // B

这里列出类型评估的规则。在B很容易,这两个方面是完全一样的:null将返回(无论何种类型,可能是)(JLS:“如果第二个和第三个操作数具有相同的类型(可能是空型),然后就是类型条件表达式。”)。在A第二项是从一个特定的类。因为这更具体,并且null可以替换类Object的对象,所以整个表达式的类型为Object(JLS:“如果第二个和第三个操作数之一为空类型,而另一个操作符的类型为引用类型,则条件表达式的类型就是该引用类型。”)。

在对表达式的类型求值之后,方法选择就如预期的那样。

给出的示例if有所不同:你使用两种不同类型的对象调用方法。三元条件运算符总是在编译时被评估为适合两种条件的一种类型。

2020-03-13