有人可以解释o2
的行为吗?它是编译器优化吗?它记录在JLS的某个地方吗?
public class Test {
public static void main(String[] args) {
Object o1 = new Object() {
String getSomething() {
return "AAA";
}
};
// o1.getSomething(); // FAILS
String methods1 = Arrays.toString(o1.getClass().getMethods());
var o2 = new Object() {
String getSomething() {
return "AAA";
}
};
o2.getSomething(); // OK
String methods2 = Arrays.toString(o2.getClass().getMethods());
System.out.println(methods1.equals(methods2));
}
}
产生的输出是
true
Object
没有方法getSomething
。并且由于o1
的类型为Object
,所以编译器将不允许您调用o1.getSomething
。
对于o2
,变量的类型是您在初始化期间创建的匿名内部类型。该类型具有getSomething
方法,因此编译器将允许您调用它。
有趣的是,具有命名类型不能直接执行此操作。在o2
的声明中没有使用任何类型名称来获得相同的效果,因为该类型是匿名的。