Re Более одного экземпляра анонимного внутреннего класса

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

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

Ответы

Ответ 1

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

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 миллион объектов одного класса.

Ответ 2

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

Есть доказательства того, что разработчики 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