内部クラスは通常のクラスよりも軽量ですか、それとも最終的にJavaは通常のクラスと同じように内部クラスをコンパイルしますか?
Javaのクラスは、それ自体がそれほど軽量ではなく、permgenメモリの一部を占めることを知っているので、クロージャのような関数を内部クラスとして使用するのが最善かどうか、または標準クラスでもうまくいくかどうかを知りたいですか?
内部クラスは通常のクラスよりも軽量ですか、それとも最終的にJavaは通常のクラスと同じように内部クラスをコンパイルしますか?
Javaのクラスは、それ自体がそれほど軽量ではなく、permgenメモリの一部を占めることを知っているので、クロージャのような関数を内部クラスとして使用するのが最善かどうか、または標準クラスでもうまくいくかどうかを知りたいですか?
内部クラスと匿名内部クラスはどちらもファイルにコンパイルされ.class
ます。例えば:
class Outer {
class Inner {
}
Object function() {
return new Object() {
};
}
}
.class
、、、の3つのファイルをOuter.class
生成しOuter$Inner.class
ますOuter$1.class
。それらは他のクラスよりも「軽量」ではなく、(私の知る限りでは)パフォーマンスの観点から一方を他方よりも使用することに利点はありません。もちろん、内部クラス、特に匿名の内部クラスは、通常のクラスのコーディングが難しいコンテキストで非常に役立ちますが、それは別の問題です。
内部クラスは引き続きクラスであり、ClassLoaderによってロードする必要があります。どちらかといえば、反対のことが当てはまります。非静的内部クラスは、それを所有するクラスへの参照を持っているため、親クラスがガベージコレクションされるのを防ぐことができます。
軽量ではありませんが、限界があります。AFAIK、匿名内部クラスのインスタンスを複数作成することはできないため、必要に応じて非匿名クラスを使用する必要があります。
編集1:すべてのコメントと説明に感謝します。これをよりよく理解するのを手伝ってください...匿名内部クラスの複数のインスタンスを持つことができることを理解していますが、たとえば、単一の匿名内部ActionListenerオブジェクトを宣言する場合、使用せずにそのクラスの複数のインスタンスとそのクラスのみを持つにはどうすればよいですか?反射?事前に感謝します(または私自身の質問でこれを尋ねるべきですか?)!
OK、噛みつかないので...コードでデモンストレーションしましょう。ここで匿名の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を作成し、このクラスのオブジェクトも一挙に作成します。私がいつも教えられてきたこと、ここでの私の投稿の冒頭で述べた(そしてうんざりした)ことは、この匿名のクラスの別のオブジェクトを作ることは不可能ではないにしても(反射の魔法なしでは)難しいということでした。オブジェクトは1つしか作成できません。必要なオブジェクトが1つだけの場合は、これで問題ありません。しかし、他の状況では、それはうまくありません。そして確かに、forループのように、複数の同様の匿名ActionListenerクラスを作成できます。
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によって使用され、状態があり、その動作がこの状態に依存する場合に重要になる可能性があります。同意?同意しませんか?ご入力いただきありがとうございます!