Есть ли издержки производительности для закрытого внутреннего класса в Java? - PullRequest
12 голосов
/ 10 февраля 2011

Когда у меня есть внутренние классы с закрытыми методами или полями, компилятор должен создавать синтетические методы доступа, защищенные пакетами, чтобы позволить внешнему классу обращаться к этим закрытым элементам (и наоборот).

Чтобы избежать этого, я обычно делаю все поля, методы и конструкторы защищенными пакетами вместо приватных.

Но как насчет видимости самого класса? Есть ли накладные расходы на

 private static class A {
      A(){}
 }

против

 static class A {
      A(){}
 }

Обратите внимание, что конструктор защищен пакетами в обоих случаях, или изменение класса private делает это?

Ответы [ 3 ]

18 голосов
/ 10 февраля 2011

Вы пробовали скомпилировать и сравнить байт-код? Вот мои результаты. Для:

public class Example {
  public static void main(String[] args) {
    System.out.println("Hello world!");
  }
  private static class A {
    A(){}
  }
}

Выше приведены следующие файлы * .class:

-rw-r--r--    1 michaelsafyan  staff   238 Feb 10 00:11 Example$A.class
-rw-r--r--    1 michaelsafyan  staff   474 Feb 10 00:11 Example.class

Теперь, если я переместу файлы классов, удалим модификатор private и перекомпилирую, я получу:

 -rw-r--r--    1 michaelsafyan  staff   238 Feb 10 00:15 Example$A.class
 -rw-r--r--    1 michaelsafyan  staff   474 Feb 10 00:15 Example.class

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

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

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

8 голосов
/ 10 февраля 2011

Не должно быть разницы в производительности между закрытым внутренним классом и не закрытым внутренним классом.

Не должно быть разницы в производительности между статическим внутренним классом (частным или нет) и внешним классом.

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

4 голосов
/ 10 февраля 2011

Маловероятно, что это когда-либо вызовет какое-либо существенное замедление.

Одна проблема, о которой следует знать с нестатическими внутренними классами, заключается в том, что они содержат ссылку на экземпляр включающего класса.

Таким образом, это может привести к «утечкам памяти», так как включающий экземпляр не может быть собран мусором.Если вы передаете экземпляры внутренних классов вызывающим, вы также передаете экземпляр включающего класса.

Это не относится к статическим внутренним классам!

Не рекомендуется делать пакет защищенным для всех полей для предотвращения синтетических методов.Вы отказываетесь от инкапсуляции, что очень важно иметь.Каковы ваши проблемы?Размер файлов вашего класса для дополнительного кода?

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