简体   繁体   English

使用存储在变量中的嵌套类实例访问外部类实例?

[英]Access outer class instance using nested class instance stored in a variable?

Consider the following classes: 考虑以下类别:

public class A {
    public int a;

    public class B {
         public int b;

         public void foo() {
             System.out.println(A.this.a);
             System.out.println(this.b);
         }
    }
}

In foo , I access the outer A instance from within B using the syntax A.this . foo ,我使用语法A.thisB内部访问外部A实例。 This works well because I'm trying to access the outer instance of A from the "current object" in B . 这很好,因为我试图从B的“当前对象”访问A的外部实例。 However, what do I do if I want to access the outer A object from a variable of type B ? 但是,如果我想从类型B变量访问外部A对象,该怎么办?

public class A {
    public int a;

    public class B {
         public int b;

         public void foo(B other) {
             System.out.println(other.A.this.a); // <-- This is (obviously) wrong. What SHOULD I do here?
             System.out.println(other.b);
         }
    }
}

What's the correct syntax to access the "outer" instance from the "inner" instance other in foo ? foo other “内部”实例访问“外部”实例的正确语法是什么?

I realize I can access the outer variable a using simply other.a . 我意识到我可以使用other.a来访问外部变量a Please forgive the contrived example! 请原谅人为的例子! I just couldn't think of a better way to ask how to reach other.A.this . 我只是想不出一种更好的方法来询问如何到达other.A.this

As far as I can tell from the Java language specification, Java does not provide a syntax for such access. 据我从Java语言规范中了解到的,Java没有提供这种访问的语法。 You can work around it by providing your own accessor method: 您可以通过提供自己的访问器方法来解决此问题:

public class A {
    public int a;

    public class B {
         public int b;
         // Publish your own accessor
         A enclosing() {
             return A.this;
         }
         public void foo(B other) {
             System.out.println(other.enclosing().a);
             System.out.println(other.b);
         }
    }
}

Well, you can't do that directly, as there is no such way defined in Java language. 嗯,您不能直接执行此操作,因为Java语言中没有定义这种方法。 However, you can use some reflection hack to get the value of that field. 但是,您可以使用一些反射技巧来获取该字段的值。

Basically, the inner classes store a reference to the enclosing class in the field named this$0 . 基本上,内部类将对封闭类的引用存储在名为this$0的字段中。 You can find more detail in this other post on SO . 您可以在有关SO的另一篇文章中找到更多详细信息

Now, using reflection, you can access that field, and get the value of any attribute for that field: 现在,使用反射,您可以访问该字段,并获取该字段的任何属性的值:

class A {
    public int a;

    public A(int a) { this.a = a; }

    public class B {
         public int b;

         public B(int b) { this.b = b; }

         public void foo(B other) throws Exception {
             A otherA = (A) getClass().getDeclaredField("this$0").get(other); 
             System.out.println(otherA.a);
             System.out.println(other.b);
         }
    }
}

public static void main (String [] args) throws Exception {
    A.B obj1 = new A(1).new B(1);
    A.B obj2 = new A(2).new B(2);
    obj2.foo(obj1);
}

This will print 1, 1 . 这将打印1, 1

But as I said, this is just a hack. 但是正如我所说,这只是一个hack。 You wouldn't want to write such a code in real application. 您不想在实际应用程序中编写这样的代码。 Rather you should go with a cleaner way as depicted in @dashblinkenlight's answer. 相反,您应该采用@dashblinkenlight答案中所描述的更干净的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM