4

Я понимаю, что для создания экземпляра внутреннего класса (то есть нестатического) требуется экземпляр входящего класса. Это делает вещи немного более сложными, если охватывающий класс является абстрактным (не спрашивайте). Рассмотрим следующее.Динамическое создание внутреннего класса, вложенного внутри абстрактного класса

abstract class Outer { 
    class Inner {} 
} 

Инстанцирование Inner еще много выполнимо статически, например, анонимный класс, как это.

Inner instance = new Outer() {}.new Inner(); 

Но как же динамически выполнить то же самое с помощью Constructor.newInstance? (Обратите внимание, что я сказал динамически, предположим, что вы не знаете имя внешнего класса.) Вам нужно передать экземпляр окружающего класса для первого аргумента в соответствии с JLS 15.9.3, и если есть способ создать что-то на лету, чтобы удовлетворить абстрактный параметр, я не знаю об этом (бонусные баллы за любые идеи там).

Короче говоря, я случайно попал в null, вот так.

Constructor<Inner> constructor = Inner.class.getDeclaredConstructor(Outer.class); 
Object argument = null; 
Inner instance = constructor.newInstance(argument); 

Представьте мое удивление, когда это сработало. Мой вопрос: зачем это работает? И это всегда будет работать?

+1

«Не спрашивайте» - старайтесь не спрашивать ... – 2010-12-10 11:20:34

+1

@BertF Ha. Если вы знаете, я пишу метод, который пытается создать экземпляр данного класса с максимальной эффективностью, и я хочу обрабатывать все возможные случаи. Внутренний класс, вложенный внутри абстрактного класса, является одним из таких возможных случаев. – gdejohn 2010-12-10 19:04:49

ответ

5

Он работал, потому что конструктор просто устанавливает поле Outer.this. Вероятно, он должен проверить, что его значение не равно null (так что он не работает быстро), но быстрее, если нет.

Я бы не полагался на то, что он всегда работает, есть все возможности, что разные JVM, даже разные обновления будут работать по-другому.

Основываясь на вашем предыдущем примере, это должно работать.

Inner instance = constructor.newInstance(new Outer(){}); 
Смежные вопросы