Оптимизирует ли компилятор анонимные классы, которые не добавляют / не переопределяют методы? - PullRequest
1 голос
/ 04 ноября 2011

Мне было интересно, оптимизирует ли компилятор (ECJ, javac или вы можете назвать ваш любимый компилятор) анонимные классы, которые не добавляют или не переопределяют методы своего базового класса.

Например, для кода, который выглядит следующим образом:

Фрагмент A:

Human h = new Human("John", 30);
h.setX(12.5);
h.setY(15.3);
//..
Eat(h);

Я бы всегда предпочел синтаксис:

Фрагмент B:

Eat(new Human("John", 30){
    {
        setX(12.5);
        setY(15.3);
        //..
    }
});

Однако я понимаю, что в отличие от ключевого слова WITH, которое есть в vb.net, это не просто синтаксический сахар. То, что мы говорим компилятору, это создание анонимного подкласса Human, конструктор которого состоит из кода внутри фигурных скобок (и поэтому мы не можем использовать этот синтаксис-сахар для конечных классов).

Проблема в том, что я использую этот синтаксис-сахар все время (как, например, переопределение onclick в слушателях пользовательского интерфейса и т. Д.), Это как один из моих стилей / привычек кодирования.

Отсюда вопрос:

  1. Оптимизирует ли компилятор этот вид синтаксиса? (то есть он понял, что не нужно создавать анонимные классы, и производительность Snippet B будет такой же, как Snippet A )

  2. Если ответом на (1) является «нет», мне было бы интересно узнать, является ли это (изобилие анонимных классов больше, чем ожидалось из-за этого стиля кодирования) заметным Настоятельно рекомендуется, чтобы в будущих проектах (приложениях для среднего мобильного устройства) мы всегда придерживались стиля в Snippet A ?

Ответы [ 2 ]

1 голос
/ 04 ноября 2011

Да, он (всегда) генерирует анонимный класс (называемый Human $ 1). Вы можете убедиться в этом, изучив файлы классов, которые выводятся. В качестве выходных данных вы должны иметь класс Human.class и Human $ 1.class.

Что касается влияния на производительность, то будет два класса (больше, больше работы для ВМ), ссылки от одного к другому (потому что анонимный внутренний класс будет иметь ссылку на внешний класс). Полагаю, это может повлиять на производительность, но только незначительное. Вы должны проверить это.

Тем не менее, это не особенно идиоматическая Java, чтобы делать это таким образом. Идиоматическим способом было бы иметь другого конструктора.

1 голос
/ 04 ноября 2011

Компилятор создаст отдельный двоичный класс.

Например, если у вас есть

class Foo{

}

class Bar{
  Foo otherFoo = new Foo(){

  }
}

В вашем каталоге bin / target у вас будет три класса

  • Bar.class
  • Bar $ 1.class
  • Foo.class

Здесь анонимный подкласс Bar$1.class

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...