Are Inner Classes lightweight?
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 the开发者_StackOverflow社区y 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?
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.
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.
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!
精彩评论