4

クレイジーな Java スコープ ルールのすべてが頭を混乱させており、public static voidナンセンスは問題を解決していません。これまで私が使用してきたすべてのプログラミング言語は、レキシカル スコープまたはアクセス修飾子を使用しないその近似のいずれかです。つまり、内側のものは外側のものをキャプチャし、内側のものがある限り外側のものにアクセスできます。

では、Java の内部クラスのスコープ規則を理解するにはどうすればよいでしょうか。それらは外部クラスで宣言された変数にアクセスできますか、それとも、すべてのpublic static privateが浮かんでいるために心配しなければならないいくつかの奇妙なエッジケースがありますか?

4

6 に答える 6

17

静的にネストされたクラス1は、アクセス修飾子に関係なく、外部クラスのすべてのメンバーにアクセスできることを除いて、外部クラスとまったく同じです。これらは外部クラスのインスタンスとは別に存在するため、外部クラスのインスタンス変数または非静的メソッドにアクセスするには、インスタンスへの参照が必要です。

非静的なネストされたクラス(内部クラスと呼ばれる)は、外部クラスのインスタンスのコンテキストでのみ存在します。構築thisされると、自動的に生成される2番目のフィールドがあり、構文を使用して内部クラス内からアクセスできますOuter.this。内部クラスの各インスタンスは、外部クラスの単一のインスタンスで囲まれています。この場合も、静的にネストされたクラスのすべてのアクセス権限が内部クラスに適用されます。ただし、外部クラスのインスタンスがすでに使用可能であるため、外部クラスのインスタンス変数とメソッドに自動的にアクセスできます。

内部クラスとアクセス指定子の優れた(そして非常に詳細な)議論については、内部クラス仕様を読むことができます。特に、ネストされたクラスがprivateその外部クラスのメンバーにアクセスする方法について説明します。より穏やかに読むのは、ネストされたクラスのチュートリアルです。

トピック外:次のクラス構造があるとします。

public class O {
    public O() { ... }

    public class I { // an inner class
        public I() { ... }
        ...
    }
    ...
}

そして、あなたは次のインスタンスを作成しましたO

O outer = new O();

ここで、のインスタンスを作成するとしますO.Inew O.I()の新しいインスタンスをIの特定のインスタンスで囲む必要があるため、単に使用することはできませんO。このために、Javaは次の構文を提供します。

O.I inner = outer.new O.I();

次に、を参照するようinnerに2番目thisのフィールドが設定されますouter

この「修飾new演算子」構文は、内部クラスにのみ使用されることに注意してください。ネストされたクラスの場合Iは不要です(実際にはエラーです)。static

1  「静的内部クラス」というフレーズに出くわすことがよくあります(恥ずかしいことに、この回答の以前のバージョンを含みます)。これは誤った用語です。Javaでは、「内部クラス」は具体的にはstaticネストされていないクラスです。

于 2011-01-31T06:03:21.183 に答える
3

あなたは区別する必要があります:

  • 静的内部クラスは、宣言外のすべての静的メンバーにアクセスできます。
  • インスタンス内部クラスは、宣言外のすべてのクラスメンバーにアクセスでき、宣言されている関数の最終フィールドにもアクセスできます。

非静的内部クラスには、外部クラスのインスタンスを持つ隠れた変数もあり、そこでメンバーにアクセスできることに注意してください。また、参照されるすべてのfinalフィールド(したがって、finalである必要があります)は、内部クラスがインスタンス化されるときに、他の非表示のメンバー変数の内部クラスにコピーされます。

例:

public void doStuff(final int a, int b) {
    final int c; // Can be referenced
    int d;       // Cannot be referenced, not final

    executer.execute( new Runnable() {
        public void run() {
            System.out.println("a: "+a+"  c: "+c);
        }
    }

    b++; // Not final, not referencable
    System.out.println(b);
}
于 2011-01-31T06:00:48.417 に答える
3

それが役立つかどうかはわかりませんが、Javaチュートリアルから:

入れ子になった静的クラス

クラスのメソッドや変数と同様に、ネストされた静的クラスはその外側のクラスに関連付けられます。また、静的クラス メソッドと同様に、入れ子になった静的クラスは、それを囲むクラスで定義されたインスタンス変数またはメソッドを直接参照することはできません。オブジェクト参照を介してのみ使用できます。注:ネストされた静的クラスは、他のトップレベル クラスと同様に、その外側のクラス (および他のクラス) のインスタンス メンバーと対話します。実際には、入れ子になった静的クラスは、パッケージングの便宜のために別のトップレベル クラスに入れ子になったトップレベル クラスの動作です。

内部クラス[非静的ネスト クラス?]

インスタンス メソッドや変数と同様に、内部クラスはそれを囲むクラスのインスタンスに関連付けられ、そのオブジェクトのメソッドやフィールドに直接アクセスできます。また、内部クラスはインスタンスに関連付けられているため、静的メンバー自体を定義することはできません。

ネストされたクラスに関する Java チュートリアルを確認する必要があります。

于 2011-01-31T06:05:26.550 に答える
0

内部クラスのルール

  1. 内部クラスによってアクセスされる外部クラス
  2. 内部クラスは外部クラスからアクセスできません
  3. 内部クラスのメンバーはメソッドのみを使用し、クラス内のメンバーのみが完全な情報にアクセスします
于 2013-08-21T00:17:07.560 に答える