Close

02.02.2015

Class.this и object.new для внутренних классов в Java

В проекте по исследованию ИВП мы используем Java. Не так давно проводя рефакторинг уже написанного кода, я столкнулся с ситуацией, когда из внутреннего класса нужно было вызвать метод, в параметр которого нужно было передать ссылку на объект внешнего класса. Я набрал в гугле «java inner class access outer object» и..

Погуглив, я обнаружил две новые для себя конструкции Java, возможно для вас они также покажутся интересными:

1. Class.this

class Outer {
    int x = 5;
    class Inner {
        int x = 10;
        public void test() {
            System.out.println( Outer.this.x );
        }
    }
    public void test() {
        new Inner().test();
    }
}

Т.е. с помощью такой конструкции вы можете сделать именно то, что мне было нужно — получить из внутреннего класса ссылку на объект внешнего класса. Это часто бывает нужно, когда вы работаете с EventListener’ами.

2. object.new

Попробуйте скомпилировать вот этот невинный на первый взгляд код:

public class Test {
    static void main()
    {
        innerTest inner=new innerTest(); // тут ошибка
    }
    
    public class innerTest{
        
    }
}

И вы получите следующую ошибку компиляции: Error: java: non-static variable this cannot be referenced from a static context . Все дело в том, что при создании объектов внутренних классов Java необходимо иметь ссылку на объект внешнего класса (см. п. 1 выше 🙂 ). Поэтому, чтобы код мог быть скомпилирован строчку с ошибкой нужно переписать так:

innerTest inner=new Test().new innerTest();

или так:

Test test=new Test();
innerTest inner=test.new innerTest();

Последнее выглядит достаточно необычно, согласитесь 😉

One Comment on “Class.this и object.new для внутренних классов в Java

Михаил Павлов
02.02.2015 в 15:40

да выглядит необычно.
но тут ты знаешь где этот Outer и он не далеко.
а обычно, та или не та задача, но часто есть возможность инжектировать что-то через IOC или анотацию. но эта штука которую инжектируют должна легко находится, в каком то доступном Scope.
еще у меня возникло ощущение, что Outer.this.x это статический метод доступа, но вроде бы и нет.
действительно не обычно.

Ответить

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *