java - 方法重载并选择最具体的类型

标签 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 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/

相关文章:

Java单元测试: Test from public method or package private method

java - 为什么不使用枚举?

运行时类型解析的 Java 最佳实践

java - 使用 String 或 StringBuilder 来保留大文本是什么?

java - 为什么这段代码不抛出 NullPointerException

java - 避免 JavaFX 中跨类的静态

c# - 静态属性引用非静态方法

Class.forName() 重载版本的 Java 用例

c# - 方法的通用接口(interface)重载?

java - 服务的访问控制(设计决策)