ネストされたクラスは、別のクラス内で定義されたクラスです。これには以下があります:
匿名クラスの例:
Button b = new Button(); b.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // クリック時の動作 } });
特徴:
内部クラス(非静的内部クラス)は静的メソッドや変数を持つことができますか?
答え: いいえ、持つことができません。ただし、定数(static final)を除きます。静的ネストされたクラスのみがstaticメンバーを持つことができます。
例(エラー):
class Outer { class Inner { static int x = 10; // コンパイルエラー! } }
正しいコード:
class Outer { static class StaticNested { static int x = 10; // OK } }
ストーリー
Androidアプリケーションで、イベントハンドラーとしてinner classを使用しました。ハンドラーはstaticフィールドに保存され、Activityへの暗黙の参照を保持していたため、Activityが破棄されるとメモリリークが発生し、アプリケーションが「漏れ始め」、最終的にはOutOfMemoryErrorに至りました。
ストーリー
マイクロサービスの1つで、外部変数(イテレータ)を参照する匿名クラスを使用していました。リファクタリング後、変数はeffectively finalではなくなり、コードがコンパイルされなくなった — 開発者はこの制約を思い出すまで原因を長時間探しました。
ストーリー
ライブラリ内でinner class内部に静的変数を使用して、これは一般的なプラクティスだと思っていました。新しいJDKのバージョンでは、標準が制約を厳守するようになったため、プロジェクトがコンパイルされなくなりました。緊急にアーキテクチャの再設計が必要でした。