【发布时间】:2015-04-07 06:12:13
【问题描述】:
class A {
private int foo;
void bar(B b) { b.foo = 42; }
}
class B extends A { }
编译失败,报错:
A.java:3: error: foo has private access in A
void bar(B b) { b.foo = 42; }
^
1 error
向基类添加强制转换使其工作。
void bar(B b) { ((A) b).foo = 42; }
有人能解释一下为什么第一个 sn-p 是非法的吗?被禁止的原因是什么? JLS 是这样说的:
否则,成员或构造函数被声明为
private,并且当且仅当它出现在包含成员或构造函数声明的顶级类(第 7.6 节)的主体内时才允许访问。
据我所知,我的代码符合这个措辞。那么这是 Java 编译器的错误,还是我对 JLS 的解释不正确?
(注意:我不是在寻找变通方法,比如创建变量protected。我知道如何解决这个问题。)
【问题讨论】:
-
@John Kugelman:您的陈述“为什么我不能从
A类的方法访问A.foo?”不太正确。实际上,您正在尝试从A类的方法访问B.foo。但是根据 JLS §8,2,子类B不会继承私有成员。 JLS §6.6 说通过限定名称访问成员需要应用访问控制。因此编译器会查看B中的类成员foo是否可访问,但B中没有这样的成员。尽管如此,它还是好心地告诉您,您的预期继承失败了,因为foo has private access in A。