Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to change the outer class instance of an inner class in Java?

Tags:

java

In Java, whenever an inner class instance is created, it is associated with an instance of an outer class. Out of curiosity, is it possible to associate the inner class with another instance of an outer class instead?

like image 649
Casebash Avatar asked Mar 02 '10 23:03

Casebash


People also ask

Is it possible to override a inner classes?

No, you cannot override private methods in Java, private methods are non-virtual in Java and access differently than non-private one. Since method overriding can only be done on derived class and private methods are not accessible in a subclass, you just can not override them.

Can outer Java classes access inner classes private member?

Conclusion. Outer classes can access inner class private members in Java until a non-static member accesses it from a static context or an inaccessible scope. Inner classes can access the variables of the outer class, including the private instance variables.

How do you create an inner class instance from outside the outer class instance code?

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax: OuterClass outerObject = new OuterClass(); OuterClass. InnerClass innerObject = outerObject.

Can an inner class extend its outer class?

Inner class can extend it's outer class. But, it does not serve any meaning. Because, even the private members of outer class are available inside the inner class. Even though, When an inner class extends its outer class, only fields and methods are inherited but not inner class itself.


2 Answers

Yes, this is possible, although it sounds like a really bad idea to me. The idea is to set the otherwise final pointer to the outer instance using reflection (which is not guaranteed to succeed).

import java.lang.reflect.*;

public class Me {
    final String name;

    Me(String name) {
        this.name = name;
    }

    class InnerMe {     
        String whoAreYou() {
            return name;
        }
    }   

    InnerMe innerSelf() {
        return new InnerMe();
    }

    public static void main(String args[]) throws Exception {
        final Me me = new Me("Just the old me!");
        final InnerMe innerMe = me.innerSelf();
        System.out.println(innerMe.whoAreYou()); // "Just the old me!"
        Field outerThis = innerMe.getClass().getDeclaredFields()[0];
        outerThis.setAccessible(true);
        outerThis.set(innerMe, new Me("New and improved me!"));
        System.out.println(innerMe.whoAreYou()); // "New and improved me!"
    }

}

The crucial part here is outerThis.setAccessible(true); -- a SecurityManager could enforce a policy that prohibits this from succeeding.

like image 192
polygenelubricants Avatar answered Sep 21 '22 15:09

polygenelubricants


If you are speaking about instantiation time, it's possible using the following syntax:

public class Outer {
    public class Inner {}
}
...
Outer o = new Outer();
Outer.Inner i = o.new Inner();

However, it's not possible (without setAccessible(true)) to associate the existing instance of inner class with the other instance of outer class, because the field pointing to the enclosing instance is final:

javap Outer$Inner

Compiled from "Outer.java"
public class Outer$Inner extends java.lang.Object{
    final Outer this$0;
    public Outer$Inner(Outer);
}
like image 44
axtavt Avatar answered Sep 20 '22 15:09

axtavt