在回顾var
特性之后,可以看到这里
在使用JDK 10设置Eclipse/IntelliJ时遇到了困难,因此,我请求具有工作Java 10环境的堆栈溢出用户的帮助。
请考虑以下几点:
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()。
真的是这样吗?
发布于 2018-04-10 04:10:31
由于空指针为在线Java10编译器提供了一个链接,我得到了以下有趣的结果:
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玩了一会儿,并想出了这个有趣的行为--再次感谢空指针将它提到为为什么我们不能将两个推断的变量作为一个匿名类分配给对方的副本。
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
关键字的语法糖角色。
令人惊讶的是,错误消息并没有得到更精确的处理--目前它没有什么意义,因为在错误中显示的类型名称是相同的!
https://stackoverflow.com/questions/49744891
复制相似问题