Внутренние классы легки? - PullRequest
8 голосов
/ 27 января 2011

Являются ли внутренние классы более легкими, чем обычные классы, или, в конце концов, java компилирует внутренние классы так же, как обычные классы?

Я знаю, что классы в java не все очень легковесны, и они занимают часть памяти permgen, поэтому я хотел бы знать, лучше ли использовать закрывающие функции в качестве внутренних классов или стандартные классы хорошо?

Ответы [ 3 ]

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

Внутренние классы и анонимные внутренние классы компилируются до .class файлов. Например:

class Outer {
     class Inner {

     }

     Object function() {
          return new Object() {

          };
     }
}

Создает три .class файла, Outer.class, Outer$Inner.class и Outer$1.class. Они не более «легки», чем другие классы, и (насколько мне известно) нет никакого преимущества в использовании одного над другим с точки зрения производительности. Конечно, внутренние классы и особенно анонимные внутренние классы действительно полезны в тех случаях, когда обычные классы сложнее кодировать, но это отдельная проблема.

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

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

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

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

edit 1: Спасибо за все комментарии и разъяснения,Пожалуйста, помогите мне лучше понять это ... Я понимаю, что у вас может быть несколько экземпляров анонимных внутренних классов, но если я объявляю один анонимный внутренний объект ActionListener, например, как я могу иметь несколько экземпляров этого класса и только этот класс без использования отражения?Заранее спасибо (или я должен задать это в своем собственном вопросе?)!

ОК, так как я не получаю никаких укусов ... Позвольте мне продемонстрировать с помощью кода.Скажем, я создаю анонимный ActionListener здесь:

  JButton button = new JButton("Button");

  button.addActionListener(new ActionListener() {
     @Override
     public void actionPerformed(ActionEvent arg0) {
        System.out.println("Button says \"Foo!\"");
     }

  });

  JOptionPane.showMessageDialog(null, button);

Я создаю анонимный ActionListener, а также создаю объект этого класса одним махом.То, чему меня всегда учили, то, что я упомянул в верхней части своего поста здесь (и получил унылость), это то, что трудно, если не невозможно (без магии отражения) сделать другой объект этого анонимного класса, чтоможно создать только один объект, и в ситуациях, когда нужен только один объект, это нормально.Но в других ситуациях это не хорошо.И конечно, вы можете создать несколько похожих анонимных классов ActionListener, как в цикле for:

   JPanel panel = new JPanel(new GridLayout(5, 5));
  JButton[] buttons = new JButton[25];
  for (int i = 0; i < 25; i++) {
     final int btnNumber = i;
     buttons[i] = new JButton(String.valueOf(btnNumber));
     buttons[i].addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
           System.out.println("From button " + btnNumber);
        }
     });
     panel.add(buttons[i]);
  }
  JOptionPane.showMessageDialog(null, panel);

Но даже в этом случае каждый анонимный класс, созданный здесь, отличается.Это может иметь значение, если один и тот же тип слушателя используется несколькими JButtens, что у него есть состояние, и его поведение зависит от этого состояния.Согласен?Не согласен?Заранее спасибо за любой вклад!

...