Вопрос-ответ

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

Получение доступа к объекту внешнего класса из объекта внутреннего класса

У меня есть следующий код. Я хочу получить объект внешнего класса, с помощью которого я создал объект внутреннего класса 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 :-( ");
}
}
}

РЕДАКТИРОВАТЬ: Ну, некоторые из вас, ребята, предложили изменить внутренний класс, добавив метод:

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

Но что, если у меня нет контроля для изменения внутреннего класса, тогда (просто для подтверждения) есть ли у нас какой-то другой способ получения соответствующего объекта внешнего класса из объекта внутреннего класса?

Переведено автоматически
Ответ 1

Внутри самого внутреннего класса вы можете использовать OuterClass.this. Это выражение, которое позволяет ссылаться на любой лексически объемлющий экземпляр, описано в JLS как квалифицированный this.

Я не думаю, что есть способ получить экземпляр извне кода внутреннего класса. Конечно, вы всегда можете ввести свое собственное свойство:

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

РЕДАКТИРОВАТЬ: Экспериментально похоже, что поле, содержащее ссылку на внешний класс, имеет доступ на уровне пакета - по крайней мере, с JDK, который я использую.

РЕДАКТИРОВАТЬ: используемое имя (this$0) действительно допустимо в Java, хотя JLS не рекомендует его использовать:


Символ $ следует использовать только в механически сгенерированном исходном коде или, в редких случаях, для доступа к уже существующим именам в устаревших системах.


Ответ 2

OuterClass.this ссылается на внешний класс.

Ответ 3

Вы могли бы (но не должны) использовать отражение для этой работы:

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

Конечно, имя неявной ссылки крайне ненадежно, поэтому, как я уже сказал, вам не следует :-)

Ответ 4

Более общий ответ на этот вопрос включает затененные переменные и способы доступа к ним.

В следующем примере (из Oracle) переменная x в main() является затеняющей 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();
}
}

Запуск этой программы выведет:

x=0, Test.this.x=1

Подробнее на: http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6

java