7

在查看此处var所见的功能后:

我在使用 JDK 10 设置 Eclipse/IntelliJ IDEA IDE 时遇到了困难,因此我向拥有 Java 10 环境的 Stack Overflow 用户寻求帮助。

考虑以下:

public class A {
   public void someMethod() { ... }
}
public class B extends A{
   @Override
   public void someMethod() { ... }
}
...
...
...
var myA = new A(); // Works as expected
myA = new B(); // Expected to fail in compilation due to var being
               // syntactic sugar for declaring an A type
myA = (A) (new B()); // Should work
myA.someMethod(); // The question - which someMethod implementation is called?

使用时var,我希望 JVM 能够识别变量所持有的派生类类型。并在执行 myA.someMethod() 时执行 B:someMethod() 而不是 A:someMethod()。

真的是这样吗?

4

1 回答 1

9

感谢nullpointer提供了一个在线 Java 10 编译器的链接,我得到了以下有趣的结果:

public class Main {
    static class A {
           public void someMethod() { System.out.println(this.getClass().getName()); }
    }
    static class B extends A{
           @Override
           public void someMethod() { System.out.println("Derived: " + this.getClass().getName()); }
    }
    public static void main(String[] args) {
        var myA = new A();
        myA.someMethod();
        myA = new B(); // does not fail to compile!
        myA.someMethod();
    }
}

和输出:

Main$A // As expected
Derived: Main$B  // As expected in inheritance

结论 - var 是语法糖: var myA = new A()相当于A myA = new A(), 与它相关的所有 OOP。

PS:我尝试与持有匿名类的 var 玩一点,并想出了这个有趣的行为 - 再次感谢nullpointer提到它作为我们为什么不能将两个推断变量分配为匿名类的副本彼此

static interface Inter {
    public void method();
}

public static void main(String[] args) {
    var inter = new Inter() {
        @Override
        public void method() {System.out.println("popo");}
    };
    inter.method();
    inter = new Inter() {
        @Override
        public void method() {System.out.println("koko");}
    };
    inter.method();
}

和输出:

Main.java:11: error: incompatible types: <anonymous Inter> cannot be converted to <anonymous Inter>
        inter = new Inter() {
                ^

由于第二个匿名类类型不同于第一个匿名类类型,对 var 的第二次分配失败 - 强制执行var关键字的语法糖角色。

令人惊讶的是,错误消息并没有更精确 - 目前它没有什么意义,因为错误中显示的类型名称是相同的!

于 2018-04-10T04:10:31.740 回答