从内部类对象获取外部类对象

pea*_*kit 228 java inner-classes

我有以下代码.我想掌握使用它创建内部类对象的外部类对象inner.我该怎么做?

public class OuterClass {

    public class InnerClass {
        private String name = "Peakit";
    }

    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        InnerClass inner = outer.new InnerClass();
       // How to get the same outer object which created the inner object back?
        OuterClass anotherOuter = ?? ;

        if(anotherOuter == outer) {
             System.out.println("Was able to reach out to the outer object via inner !!");
        } else {
             System.out.println("No luck :-( ");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:嗯,你们中的一些人建议通过添加一个方法来修改内部类:

public OuterClass outer() {
   return OuterClass.this;
}
Run Code Online (Sandbox Code Playgroud)

但是如果我没有控制来修改内部类,那么(只是为了确认)我们还有其他方法从内部类对象获取相应的外部类对象吗?

Jon*_*eet 310

在内部类本身中,您可以使用OuterClass.this.此表达式允许引用任何词汇封闭实例,在JLS中描述为Qualifiedthis.

认为没有办法从内部类的代码之外获取实例.当然,您可以随时介绍自己的房产:

public OuterClass getOuter() {
    return OuterClass.this;
}
Run Code Online (Sandbox Code Playgroud)

编辑:通过实验,看起来持有对外部类的引用的字段具有包级别访问权限 - 至少使用我正在使用的JDK.

编辑:使用(这个名字this$0)在Java中确实有效,虽然JLS阻碍了它的用法:

$字符应仅用于机械生成的源代码,或者很少用于访问遗留系统上的预先存在的名称.

  • @peakit:据我所知,除非你使用反射,否则你运气不好.虽然它确实违反了封装,但如果内部类不想告诉你它的外部实例是什么,那么你应该尊重它并尝试设计你不需要它. (7认同)

bma*_*ies 32

OuterClass.this 引用外部类.

  • 但只在OuterClass的源中/内.而且我认为这不是OP想要的. (5认同)
  • 这并不能回答问题 (2认同)

Luk*_*der 22

您可以(但不应该)使用反射来完成工作:

import java.lang.reflect.Field;

public class Outer {
    public class Inner {
    }

    public static void main(String[] args) throws Exception {

        // Create the inner instance
        Inner inner = new Outer().new Inner();

        // Get the implicit reference from the inner to the outer instance
        // ... make it accessible, as it has default visibility
        Field field = Inner.class.getDeclaredField("this$0");
        field.setAccessible(true);

        // Dereference and cast it
        Outer outer = (Outer) field.get(inner);
        System.out.println(outer);
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,隐含引用的名称是完全不可靠的,所以正如我所说,你不应该:-)