Getting hold of the outer class object from the inner class object
Получение доступа к объекту внешнего класса из объекта внутреннего класса
У меня есть следующий код. Я хочу получить объект внешнего класса, с помощью которого я создал объект внутреннего класса inner. Как я могу это сделать?
publicstaticvoidmain(String[] args) { OuterClassouter=newOuterClass(); InnerClassinner= outer.newInnerClass(); // How to get the same outer object which created the inner object back? OuterClassanotherOuter= ?? ;
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
Вы могли бы (но не должны) использовать отражение для этой работы:
// Create the inner instance Innerinner=newOuter().newInner();
// Get the implicit reference from the inner to the outer instance // ... make it accessible, as it has default visibility Fieldfield= Inner.class.getDeclaredField("this$0"); field.setAccessible(true);
// Dereference and cast it Outerouter= (Outer) field.get(inner); System.out.println(outer); } }
Конечно, имя неявной ссылки крайне ненадежно, поэтому, как я уже сказал, вам не следует :-)
Ответ 4
Более общий ответ на этот вопрос включает затененные переменные и способы доступа к ним.
В следующем примере (из Oracle) переменная x в main() является затеняющей Test.x: