If I have an instance of an inner class, how can I access the outer class from code that is not in the inner class? I know that within the inner class, I can use Outer.this
to get the outer class, but I can't find any external way of getting this.
For example:
public class Outer {
public static void foo(Inner inner) {
//Question: How could I write the following line without
// having to create the getOuter() method?
System.out.println("The outer class is: " + inner.getOuter());
}
public class Inner {
public Outer getOuter() { return Outer.this; }
}
}
Where is the problem for simply write this?
}
The bytecode of the
Outer$Inner
class will contain a package-scoped field namedthis$0
of typeOuter
. That's how non-static inner classes are implemented in Java, because at bytecode level there is no concept of an inner class.You should be able to read that field using reflection, if you really want to. I have never had any need to do it, so it would be best for you to change the design so that it's not needed.
Here is how your example code would look like when using reflection. Man, that's ugly. ;)
Can't you just do something like this:
Here is one reason you may want this behavior: You have the inner class instance and need to access a method defined in the outer class using reflection.
For the record, "inner.getClass().getDeclaredField("this$0")"works. Since the field is private, you also need to call field.setAccessible(true).
What's wrong with adding a getter when you need to access the outer class? That way you can control whether access is allowed or not.
This, in fact, is a very good question if, for example, you need to be able to check if two distinct instances of an
Innner
class share the same instance ofOuter
class (== or equals depending on the context).I'd suggest to make a general purpose interface (not absolutely required for named inner classes but can be "instancedof"/casted to):
that can be applied to any named inner class.
Then you do something like:
and this way you can access outer class from any inner class implementing
InnerClass<Outer>
interface (and check it actually implements it).If your inner class is anonymous, you can only do (thanks to Rich MacDonald for its sample):
but
InterfaceOrAbstractClass
must implementsInnerClass<Outer>
to be able to accessgetOuter()
outside of the anonymous class body!It would be so much easier if javac automatically implemented some kind of
InnerClass<Outer>
interface on ALL inner classes, and it could do that super efficiently even on anonymous classes (no sluggish introspection processing)!