4

У меня есть следующий код:Доступ наружный внутренний класс от Нестер внутреннего класса

public class Bar {} 
public class FooBar {} 

public class Foo { 

    public void method() { 
     new Bar() { 

      void otherMethod() { } 

      void barMethod() { 

       new FooBar() { 

        void fooBarMethod() { 
         Bar.this.otherMethod(); // not compiles 
        } 
       }; 
      } 
     }; 
    } 

} 

Так я есть анонимный внутренний класс, который имеет другой анонимный внутренний класс в нем. Вопрос: есть ли способ доступа к методам внешнего внутреннего класса Bar из внутреннего внутреннего класса FooBar?

+1

Это чисто теоретический вопрос или вы собирались делать это? –

+0

Это теоретический вопрос. :) – WonderCsabo

+1

Прочтите [это] (http://stackoverflow.com/questions/763543/in-java-how-do-i-access-the-outer-class-when-im-not-in-the-inner- класс). –

ответ

5

Вы можете вызвать метод напрямую, используя простое имя:

void fooBarMethod() { 
    otherMethod(); // compiles 
} 

Это потерпит неудачу, в тот момент, вы определяете другой метод с именем otherMethod() в new FooBar() анонимного класса.

Bar.this не работает, потому что это анонимный класс, имя которого указано во время компиляции. Он получит такое имя, как Foo$1. Итак, нет, у вас не может быть чего-то вроде Bar.this.


Хорошо, я написал этот исходный файл:

class Bar { } 

class FooBar { } 

public class Demo { 

    public static void main() { 
     new Demo().method(); 
    } 

    public void method() { 
     new Bar() { 

      void otherMethod() { System.out.println("Hello"); } 

      void barMethod() { 

       new FooBar() { 

        void fooBarMethod() { 
         otherMethod(); // not compiles 
        } 
       }.fooBarMethod(); 
      } 
     }.barMethod(); 
    } 
} 

Класс файлы сгенерированных будет:

Bar.class 
FooBar.class 
Demo.class 

Demo$1.class // For `new Bar()` anonymous class 
Demo$1$1.class // For `new FooBar()` anonymous class 

Теперь, давайте идти прямо к байтовому коду new FooBar() анонимного класс. Класс будет называться - Demo$1$1. Таким образом, выполнив команду javap, я получаю этот выход:

class Demo$1$1 extends FooBar { 
    final Demo$1 this$1; 

    Demo$1$1(Demo$1); 
    Code: 
     0: aload_0 
     1: aload_1 
     2: putfield  #1     // Field this$1:LDemo$1; 
     5: aload_0 
     6: invokespecial #2     // Method FooBar."<init>":()V 
     9: return 

    void fooBarMethod(); 
    Code: 
     0: aload_0 
     1: getfield  #1     // Field this$1:LDemo$1; 
     4: invokevirtual #3     // Method Demo$1.otherMethod:()V 
     7: return 
} 

final поля есть копия ссылки на new Bar() инстанции. Таким образом, otherMethod() вызывается по ссылке this$1, которая является ссылкой на экземпляр анонимного внутреннего класса new Bar(). Ну, вы пытались сделать это только, но поскольку это анонимный внутренний класс, вы не можете напрямую обратиться к ссылке this. Но это подразумевается там.


Для более детального анализа:

+0

Какова ссылка на метод 'otherMethod'? В основном, почему это работает? –

+0

Простое решение. А как насчет доступа к самому объекту «Бар» из «FooBar», возможно ли это («Bar.this'»)? – WonderCsabo

+0

@SotiriosDelimanolis Все еще декодирует его. Честно говоря, это странный код. –

0

Если вы называете их, то они не анонимные внутренние классы, они просто внутренние классы. Если вы их не назовете, вы не можете называть их явно, хотя вы можете называть их, если конфликт имен отсутствует.

Ваш код полностью недействителен, но вы создаете новый Bar, но не определяете класс Bar.

Забудьте о линии вы говорите «не компилируется» на, первый «новый бар()» не компилируется ...

+2

Мне показалось, что это просто приведенный пример, и можно предположить, что 'Bar' и' FooBar' являются существующими не финальными классами. – WonderCsabo

Смежные вопросы