Getting hold of the outer class object from the inner class object

前端 未结 8 1247
孤独总比滥情好
孤独总比滥情好 2020-11-22 02:26

I have the following code. I want to get hold of the outer class object using which I created the inner class object inner. How can I do it?

pub         


        
相关标签:
8条回答
  • 2020-11-22 02:49

    OuterClass.this references the outer class.

    0 讨论(0)
  • 2020-11-22 02:52

    Within the inner class itself, you can use OuterClass.this. This expression, which allows to refer to any lexically enclosing instance, is described in the JLS as Qualified this.

    I don't think there's a way to get the instance from outside the code of the inner class though. Of course, you can always introduce your own property:

    public OuterClass getOuter() {
        return OuterClass.this;
    }
    

    EDIT: By experimentation, it looks like the field holding the reference to the outer class has package level access - at least with the JDK I'm using.

    EDIT: The name used (this$0) is actually valid in Java, although the JLS discourages its use:

    The $ character should be used only in mechanically generated source code or, rarely, to access pre-existing names on legacy systems.

    0 讨论(0)
  • 2020-11-22 02:58
    /**
     * Not applicable to Static Inner Class (nested class)
     */
    public static Object getDeclaringTopLevelClassObject(Object object) {
        if (object == null) {
            return null;
        }
        Class cls = object.getClass();
        if (cls == null) {
            return object;
        }
        Class outerCls = cls.getEnclosingClass();
        if (outerCls == null) {
            // this is top-level class
            return object;
        }
        // get outer class object
        Object outerObj = null;
        try {
            Field[] fields = cls.getDeclaredFields();
            for (Field field : fields) {
                if (field != null && field.getType() == outerCls
                        && field.getName() != null && field.getName().startsWith("this$")) {
                    field.setAccessible(true);
                    outerObj = field.get(object);
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return getDeclaringTopLevelClassObject(outerObj);
    }
    

    Of course, the name of the implicit reference is unreliable, so you shouldn't use reflection for the job.

    0 讨论(0)
  • 2020-11-22 03:03

    You could (but you shouldn't) use reflection for the job:

    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);
        }
    }
    

    Of course, the name of the implicit reference is utterly unreliable, so as I said, you shouldn't :-)

    0 讨论(0)
  • 2020-11-22 03:03

    Have been edited in 2020-06-15

    public class Outer {
    
        public Inner getInner(){
            return new Inner(this);
        }
    
        static class Inner {
    
            public final Outer Outer;
    
            public Inner(Outer outer) {
                this.Outer=outer;
            }
        }
    
        public static void main(String[] args) {
            Outer outer = new Outer();
            Inner inner = outer.getInner();
            Outer anotherOuter=inner.Outer;
    
            if(anotherOuter == outer) {
                System.out.println("Was able to reach out to the outer object via inner !!");
            } else {
                System.out.println("No luck :-( ");
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 03:11

    if you don't have control to modify the inner class, the refection may help you (but not recommend). this$0 is reference in Inner class which tells which instance of Outer class was used to create current instance of Inner class.

    0 讨论(0)
提交回复
热议问题