加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 外部基类的访问字段

发布时间:2020-12-15 02:58:47 所属栏目:Java 来源:网络整理
导读:在 Java中,内部类通常可以访问外部类的私有成员. 在编写 Android应用程序时,我有一个静态内部类,它扩展了它的外部类. 事实证明,无法访问外部类的私有字段: class Outer { private int m_field = 1; static class Inner extends Outer { Inner() { m_field =
在 Java中,内部类通常可以访问外部类的私有成员.
在编写 Android应用程序时,我有一个静态内部类,它扩展了它的外部类.
事实证明,无法访问外部类的私有字段:
class Outer {
  private int m_field = 1;

  static class Inner extends Outer {
    Inner() {
      m_field = 2;
    }
  }
}

它给出了一个令人困惑的错误消息:

error: non-static variable m_field cannot be referenced from a static context

尽管除了班级本身之外没有什么是静态的.

当字段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 {

}

这提供了更好的错误消息:

error: x has private access in 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:

Otherwise,if the member or constructor is declared private,then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

没有转换为外部访问是不允许的,因为a)m_field是Outer的私有成员,因此它对子类是不可见的,并且b)它不是被声明的类的成员.添加强制转换意味着编译器将其视为外部,并且m_field变为可访问.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读