Getting an object of an external class from an internal object of a class

I have the following code. I want to get an object of an outer class, using which I created an inner object of the inner class. How can i do this?

 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 :-( "); } } } 

EDIT: Well, some of you guys suggested changing the inner class by adding a method:

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

But what if I do not have control over the change of the inner class, then (just for confirmation) do we have another way to get the corresponding object of the outer class from the inner object of the class?

+181
source share
9 answers

Inside the inner class, you can use OuterClass.this . This expression, which allows you to reference any lexically spanning instance, is described in JLS as Qualified this .

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

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

EDIT: From experience, it looks like the field containing the link to the external class has access to the package level - at least using the JDK that I use.

EDIT: the name used ( this$0 ) is really valid in Java, although JLS prevents it from being used:

The $ character should only be used in mechanically generated source code, or, rarely, for accessing legacy systems that already exist.

+256
source

OuterClass.this refers to an outer class.

+24
source

You could (but 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 an implicit link is completely unreliable, as I said, you shouldn't :-)

+17
source

I think this could be an abuse of using the inner class. It seems to me that you want to break the fundamental concepts of object-oriented programming. If you want to access the outer class from the inner class, include a link to the outer class so that you have access to it. When you need to do such complex things, this is usually a sign that you should review your design options.

0
source

Here is an example:

 // Test public void foo() { C c = new C(); A s; s = ((AB)c).get(); System.out.println(s.getR()); } // classes class C {} class A { public class B extends C{ A get() {return A.this;} } public String getR() { return "This is string"; } } 
0
source

I just did it like this:

 public class CherryTree { public class Cherry { public final CherryTree cherryTree = CherryTree.this; // [...] } // [...] } 

Of course, you should be able to modify the inner class, and everyone who gets the object of the inner class now has access to the object of the outer class. In my case, this is just fine.

0
source

A more general answer to this question includes hidden variables and how to access them.

In the following example (from Oracle), the variable x in main () is the shadow Test.x :

 class Test { static int x = 1; public static void main(String[] args) { InnerClass innerClassInstance = new InnerClass() { public void printX() { System.out.print("x=" + x); System.out.println(", Test.this.x=" + Test.this.x); } } innerClassInstance.printX(); } public abstract static class InnerClass { int x = 0; public InnerClass() { } public abstract void printX(); } } 

The launch of this program will be printed:

 x=0, Test.this.x=1 

More details: http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6

0
source

If you do not have control over the change to the inner class, the fix may help you (but not recommended). this $ 0 is a reference in the Inner class that tells which instance of the Outer class was used to create the current instance of the Inner class.

0
source

open class Outer {

 public Inner getInner(){ return new Inner(this,this.getClass()); } class Inner { public Inner(Outer outer, Class<? extends Outer> aClass) { System.out.println(outer); System.out.println(aClass.getName()); System.out.println(); } } public static void main(String[] args) { new Outer().getInner(); } 

}

0
source

Source: https://habr.com/ru/post/1216542/


All Articles