java – 外部基类的访问字段
在
Java中,内部类通常可以访问外部类的私有成员.
在编写 Android应用程序时,我有一个静态内部类,它扩展了它的外部类. 事实证明,无法访问外部类的私有字段: class Outer { private int m_field = 1; static class Inner extends Outer { Inner() { m_field = 2; } } } 它给出了一个令人困惑的错误消息:
尽管除了班级本身之外没有什么是静态的. 当字段m_field受到保护时,它编译没有问题. class Outer { private int m_field = 1; static class Inner extends Outer { Inner() { ((Outer)this).m_field = 2; } } } 它没有问题. 编辑: 对于一个真实的用例,请考虑这样的类: public abstract class MyItem { private int m_counter = 0; public abstract int updateSomething(); public static class CountItem extends MyItem { public int updateSomething() { m_counter++; } } public static class DoubleCountItem extends MyItem { public int updateSomething() { m_counter += 2; } } } 这是一个非常抽象的例子,但它可以用来为抽象类提供基本的实现,这些抽象类本身不需要很多代码. EDIT2: 正如@Nathan建议的那样,似乎这个问题可以通过2个类重新创建而不需要嵌套: class Base { private int x = 0; void a(Extended b) { ((Base)b).x = 1; //<-- with cast: compiles,without: error } } class Extended extends Base { } 这提供了更好的错误消息:
解决方法
你在这里看到的是,只要你在Outer的类定义中,就可以访问具有类Outer的任何东西的私有成员,包括强制转换为Outer的东西.它们必须具有相同的类(而不是作为类的实例,具有不同的具体子类).
内部类是一个复杂的问题,这是一个较小的例子: public class A { private int foo = 0; public String toString() { return "A: foo=" + foo; } public static void main(String[] args) { B b = new B(); System.out.println(b); ((A)b).foo = 1; System.out.println(b); } } class B extends A { } 这个编译,只是因为它在A的类定义中.将main方法移动到其他地方(例如,在B中),你不能再引用foo. 这是您在编码等于方法时看到的内容,您可以在其中访问同一类的另一个实例的私有字段,因为您正在编写一个类定义的方法. Java language specification,in 6.6.1 Determining Accessibility:
没有转换为外部访问是不允许的,因为a)m_field是Outer的私有成员,因此它对子类是不可见的,并且b)它不是被声明的类的成员.添加强制转换意味着编译器将其视为外部,并且m_field变为可访问. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |