Ре Более чем один экземпляр анонимного внутреннего класса - PullRequest
13 голосов
/ 27 января 2011

Это связано с моим ответом на вопрос, заданный в этой теме: Являются ли внутренние классы легкими?

Из моего чтения я помню, что если вы можете создать только один объектодин анонимный внутренний класс, и по этой причине, если вы хотите сказать, создайте класс ActionListener и хотите создать несколько объектов из этого одного класса (без использования отражения), чтобы не использовать анонимный внутренний класс, а скорее закрытый внутреннийкласс или стоять рядом с классом, но люди говорят мне, что я не прав.Может кто-нибудь уточнить это для меня?Пожалуйста, проверьте ссылку, так как она содержит более подробную информацию, но если что-то неясно, пожалуйста, спросите!

Ответы [ 2 ]

17 голосов
/ 27 января 2011

Вы можете создать любое количество анонимных объектов класса, вы можете создать их в одном месте в вашем коде (если вы не скопируете код)

ExecutorService service = ...
for(int i=0;i<1000*1000;i++) {
   final int finalI = i;
   service.submit(new Runnable() {
      public void run() {
         System.out.println("Task "+finalI+" run.");
      }
   });
}

Этот код создаст 1 миллион объектов одного класса.

4 голосов
/ 28 января 2011

Мне неясно. Возможно, если мы прочесаем спецификации, мы найдем доказательства того, что к внутренним классам следует относиться так же, как к нормальным классам. Однако в духе внутренний класс зависит от внешнего экземпляра , класс не существует за пределами экземпляра. Это отличается от "нормальных" классов, чье существование в основном вечно. Конечно, два внутренних класса двух внешних экземпляров в некоторой степени связаны друг с другом и создаются одним и тем же исходным кодом, но это не значит, что они должны быть идентичными или даже равными.

Существуют свидетельства того, что разработчики Java планировали это так, что внутренний класс в духе живет в рамках внешнего экземпляра. Например, любопытный синтаксис outerInstance.new InnerClass(). Например, нет статических переменных, нет статических инициализаторов для внутренних классов. При обсуждении разгрузки классов [1] мы видим, что аргумент на самом деле не применяется к внутренним классам, возможно, что внутренние классы могут быть выгружены! Возможно, что виртуальная машина создает новый внутренний класс для каждого нового внешнего экземпляра.

Практически это не так, внутренние классы действительно обрабатываются так же, как и обычные классы. Но концептуально я всегда буду думать о них иначе, как о частных классах.

[1] http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7

Обновление: согласно [2]

Два ссылочных типа - это один и тот же тип времени выполнения, если они ... имеют одинаковое двоичное имя

и [3]

Двоичное имя анонимного класса (§15.9.5) состоит из двоичного имени его сразу включающего типа, за которым следует $, за которым следует непустая последовательность цифр.

Таким образом, у одного анонимного класса есть одно двоичное имя, следовательно, только один тип времени выполнения. Спецификация гарантирует нам, что разные экземпляры анонимного класса имеют идентичный класс.

[2] http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.3.4

[3] http://java.sun.com/docs/books/jls/third_edition/html/binaryComp.html#44909

...