在主函数中通过内部类对象访问外部类变量

3
class Host {
    int x=2;

    class Helper {
        int x = 7;
    }

    public static void main(String[] args){
        Host ho = new Host();
        Helper he = ho.new Helper();
        System.out.println(ho.x);
        System.out.println(he.x);

    }
}

所以在这里我得到了预期的输出。
2
7

现在我想要问的是,假设我想从对象he访问ho的x属性。
也就是说,我想在这里通过Helper对象he输出2:
System.out.println(???);

我知道这样做没有用,我只是想澄清我的嵌套类的概念。我认为这应该是可能的,因为Helper对象he与Host对象ho有点“绑定”。由于没有ho就不可能有he。从Helper类内部,我可以执行System.out.println(Host.this.x);并且它有效。但我无法从main函数内部找出如何实现。

无法实现,因为在 Host ho 中没有 Helper 的实例存在。 - user180100
问题已经在这里得到回答 - https://dev59.com/kXVD5IYBdhLWcg3wL4mM - CocoGSD
4个回答

1
在早期版本的Java中,你需要使用this$0来访问外部实例,而不是Host.this。尽管规范已经改变,但该字段仍可通过反射访问:
Field this$0 = he.getClass().getDeclaredField("this$0");
Host host = (Host) this$0.get(he);
System.out.println(host.x);

我不知道其他方法(除了修改Host类以添加getXgetHost方法)。

现在,为什么没有反射就无法访问呢?我可以想到两个可能的原因:

  • 他们忘记了
  • 从实例外部访问会破坏封装性

@assylias 我想这被认为会违反封装,可能会引起关于字段访问权限的新问题。它看起来也很像其他一些语言中闭包保护变量的方式。 - Denys Séguret

1

正如其他答案所指出的那样,你不能这样做。原因在于JLS #15.8.3中定义了this的方式。

关键字this只能在实例方法、实例初始化程序或构造函数的主体中使用,或者在类的实例变量的初始化程序中使用。如果它出现在任何其他地方,将会发生编译时错误。

由于只能使用this访问封闭实例(参见JLS #15.8.4),因此只能在内部类中完成:

如果当前类不是C或C本身的内部类,则调用C.this是一个编译时错误。


0

你可以在内部类中创建一个返回外部类的方法:

class Helper {
    int x = 7;

    public Host outer() {
        return Host.this;
    }
}

// In main;
System.out.println(he.outer().x);

这类似于在Helper内访问x,但更加通用。


0

Java基础概念,宿主类可以访问内部类变量x,但反过来则不可能。您可以按照@Nikita Beloglazov的建议进行操作,但直接使用变量是不可能的。


嗯,有趣。那么我如何以另一个方向进行操作呢?我如何从ho访问hex - user1265125
你不能像评论中的@RC所说的那样。 - Pradeep Simha
哦,所以我不能用其他方式做到这一点吗?我只能通过它们独立的对象访问它们的变量吗? - user1265125
那么,你在回复中说什么意思呢:“Host类可以访问内部类变量x”? - user1265125

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接