8

Are inner classes more lightweight than normal classes, or in the end java compiles inner classes just like normal classes?

I know classes in java are not all very lightweight themselves, and they occupy part of the permgen memory, so I'd like to know if it's best to use closure-like functions as inner classes, or if standard classes would also do fine?

Waneck
  • 2,450
  • 1
  • 19
  • 31
  • 1
    The JVM has only primitive data types (`int`, `float`, etc.) and classes. There is nothing between them. – Gabe Jan 27 '11 at 03:40

3 Answers3

19

Inner classes and anonymous inner classes both compile down to .class files. For example:

class Outer {
     class Inner {

     }

     Object function() {
          return new Object() {

          };
     }
}

Will generate three .class files, Outer.class, Outer$Inner.class, and Outer$1.class. They aren't more "lightweight" than other classes, and (to the best of my knowledge) there's no advantage to using one over the other from a performance perspective. Of course, inner classes and especially anonymous inner classes are really useful in contexts where regular classes are harder to code, but that's a separate issue.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • 8
    +1. If anything inner classes are "heavier" because they contain synthetic methods and fields that the compiler creates to facilitate the special visibility rules that they have with respect to their containing class. – Thilo Jan 27 '11 at 03:50
7

Inner classes are still classes and they still have to be loaded by a ClassLoader. If anything, the opposite is true. A non-static inner class can keep the parent class from being garbage collected since it has a reference to the class which owns it.

Tim Bender
  • 20,112
  • 2
  • 49
  • 58
  • 1
    +1. In addition to the parent reference, there are also synthetic methods to allow calling "private" methods from the related classes. – Thilo Jan 27 '11 at 03:52
1

They're not light-weight, but they have limits. AFAIK, you can't create more than one instance of an anonymous inner class, and so if your needs require this, you must use a non-anonymous class.

edit 1: Thanks for all the comments and clarifications. Please help me understand this better... I understand that you can have multiple instances of anonymous inner classes, but if I declare a single anonymous inner ActionListener object for instance, how can I have multiple instances of that class and only that class without using reflection? Thanks in advance (or should I ask this in my own question?)!

OK, since I'm not getting any bites... Let me demonstrate with code. Say I create an anonymous ActionListener here:

  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);

I create an anonymous ActionListener and also create an object of this class in one fell swoop. What I've always been taught, what I mentioned at the top of my post here (and got dinged for), was that it is difficult if not impossible (without the magic of reflection) to make another object of this anonymous class, that only one object can be made, and in situations where only one object is needed, this is fine. But in other situations, it's not fine. And sure, you could create multiple similar anonymous ActionListener classes, as in a for loop:

   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);

But even so, each anonymous class created here is different. This may have significance if this same type of the listener is used by multiple JButtens, that it has state, and its behavior depends on this state. Agree? Disagree? Thanks in advance for any input!

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • 3
    You can have multiple instances of anonymous inner classes by, for example, putting the class in a `for` loop and instantiating it multiple times. I think Java requires these classes all to have the same type, but I can't remember if that's correct or not. – templatetypedef Jan 27 '11 at 03:45
  • 1
    You're over thinking it. An anonymous inner class is still a class. You can have as many instances of it as you please. You can also have as many anonymous inner classes as you want specified. The compiler handles all of this at compile time. The first anonymous specification it finds gets the lovely name of Foo$1, the second is Foo$2, and so on. Code like `new Runnable(){...}` becomes `Foo.new 1()`. – Tim Bender Jan 27 '11 at 03:58
  • Thanks for the comments and the helpful information! Please clarify for me... if I have an anonymous inner ActionListener, how can I have two distinct instances of this class (without reflexion) since it is create as the object is created. I know that I can have many instances of anonymous ActionListeners, but I'm wondering how it is possible to have multiple instances of one distinct anonymous class that has been declared. – Hovercraft Full Of Eels Jan 27 '11 at 04:06
  • Edit: as I've not received a clarification, I've created a new thread/question for this issue here: http://stackoverflow.com/questions/4820031/re-more-than-one-instance-of-an-anonymous-inner-class. Please let me know if this is OK to do. Thanks! – Hovercraft Full Of Eels Jan 27 '11 at 18:01