?

Log in

No account? Create an account
В мире нет ничего простого
Сентябрь 2, 2011
08:27 am

[Ссылка]

Previous Entry Поделиться Next Entry

Еще одна фишка из синтаксиса Java - тоже, возможно, любому опытному программисту известная, а вот мне до сих пор - нет. При написании внутренних классов (чаще всего потоков) иногда оказывается, что нужно получить доступ к непосредственно к экземпляру внешнего класса (а не его элементам) - например, чтобы куда-нибудь его передать - скажем, так:
class Outer {
    class Inner {
        //...
        public void innerMethod() {
            //...
            Outer outer = null;    // на самом деле вместо null должна быть ссылка
            SystemClass.staticMethod(outer);    // на экземпляр внешнего класса
            //...
        }
        //...
    }
}
Очевидные решения этой проблемы - либо сделать во внешнем классе поле, инициализируемое самим экземпляром ( Outer o = this; ), к которому внутренний уже получит доступ без проблем, либо (пере)определить конструктор внутреннего класса так, чтобы передавать ему ссылку на экземпляр внешнего при создании объекта. И то, и другое - очевидные костыли: первое заставляет создать "лишнее", ни для чего полезного вроде бы не нужное поле, да и вообще выглядит глупо и неопрятно, второе порой требует специально под это создавать новый класс/интерфейс, тогда как иначе это бы не потребовалось (типичный пример - создание потоков), и оставляет открытым вопрос о доступе для статических методов внутреннего класса.
Так вот, оказывается, костыли не нужны. Получить доступ к экземпляру внешнего класса позволяет вот такая странная конструкция: Outer.this . Это ссылка непосредственно на него. Выглядит не очень логично, зато, черт возьми, работает! Пригодно для работы с анонимными, неанонимными и локальными внутренними классами.
В литературе упоминаний не встречал.

Tags: ,

(2 комментария | Оставить комментарий)

Comments
 
[User Picture]
From:whitelynx
Date:Сентябрь 2, 2011 11:09 am
(Link)
Странно, если не встречал упоминаний в литературе - это в общем достаточно типичная ситуация, которая по идее должна быть описана... впрочем, я сам наизусть тоже этого не помнил - помнил, что да, есть конструкция, которая позволяет сослаться на экземпляр внешнего класса, но мне казалось, что есть ключевое слово outer, которое и обозначает такую ссылку.
[User Picture]
From:bukky_boogwin
Date:Сентябрь 3, 2011 09:12 am
(Link)
Не, такого нет... возможный был бы вариант, но, по-моему, не очень удобный: тогда в некоторых случаях его пришлось бы вызывать несколько раз подряд в случае нескольких концентрически вложенных классов (экзотическая ситуация, но возможная), а если бы один из них убрали (например,решили, что где-то отдельный поток делать не нужно), то все outer пришлось бы подправлять, а это источник ошибок. А конструкция ClassName.this работает всегда, потому что два класса одинаково поименовать невозможно, в том числе и в самом классе, хотя там она и оказывается излишней. Правда, получается, что если у нас есть класс, вложенный в другой, анонимный, то вот до этого анонимного так доступиться не получится... но это тоже экзотика, конечно.
Разработано LiveJournal.com