好吧,这是一个奇怪的情况。
看来问题是:
- 在这种情况下, 应该可以访问 私有成员(6.6.1):
否则,将声明成员或构造函数
private,并且仅当且仅当它发生在包含成员或构造函数的声明的顶级类的主体内时,才允许访问。
- 但是,私有成员不会被继承(8.2):
声明的类的成员
private不被该类的子类继承。
- 因此,
printMe
它不是匿名子类的成员,并且编译器在超类*Operation
(15.12.1)中搜索它:
如果有一个封闭的类型声明 ,该方法是该方法的成员 ,则让T为最里面的这种类型声明。搜索的类或接口是T。
该搜索策略称为“梳子规则”。 它在嵌套类及其父类层次结构中查找方法之前,可以有效地在嵌套类的父类层次结构中查找方法。
- 这就是奇怪的地方。因为
printMe
是在 也包含 在内的类中找到的PLUS
,所以调用该方法的对象被确定为的包含实例Operation
,该实例不存在(15.12.4.1):
否则,令T为方法是其成员的封闭类型声明,令 n 为整数,使得T为该类的第 n 个词法封闭类型声明,其声明立即包含方法调用。 目标引用是的第
n 个词法包围实例this。如果 不存在第 n 个按词法包围的实例,
this则是编译时错误。
简而言之,因为
printMe仅是
Operation(且未继承)成员,所以编译器被迫
printMe在不存在的外部实例上 调用。
但是,该方法仍然可以访问,我们可以通过限定调用来找到它:
@Overridedouble apply(double x, double y) {// now the superclass is searched// but the target reference is definitely 'this'// vvvvvv super.printMe(x); return x + y;}两条错误消息听起来彼此矛盾。
是的,这是语言的一个令人困惑的方面。一方面,匿名类永远不会是静态的(15.9.5),另一方面,匿名类表达式可以
出现在静态上下文中
,因此没有封闭的实例(8.1.3)。
匿名类始终是内部类。从来没有
static。内部类
I的声明发生在静态上下文中的实例没有词法包围的实例。
为了帮助理解其工作原理,下面是一个格式化示例:
类示例{ _public static void main(String ... args){_ **new Object(){ 我 无效的m(){} } **_; }_}里面的一切
_italics_都是静态的。从in中的表达式派生的匿名类
**bold**
被视为内部且非静态的(但没有的封闭实例
Example)。
由于匿名类是非静态的,因此尽管它本身是在静态上下文中声明的,但它无法声明静态的非常量成员。
*除了稍微掩盖问题之外,
Operation作为枚举的事实是完全不相关的(8.9.1):
枚举常量的可选类主体隐式定义了一个匿名类声明,该声明扩展了立即封闭的枚举类型。类主体由匿名类的通常规则控制。



