web-dev-qa-db-ja.com

Java:静的クラスと内部クラス

静的および非静的の入れ子クラスの違いは何ですか?

344

内部クラス の定義 は静的にはできませんので、「静的と非静的の入れ子の違いは何ですか?」という質問に答えます。クラス?"

静的でない入れ子クラスは、それが入れ子になっているクラスのメンバーにフルアクセスできます。静的入れ子クラスは入れ子インスタンスへの参照を持たないため、静的入れ子クラスは、入れ子になっているクラスのインスタンスの非静的メソッドを呼び出したり、非静的フィールドにアクセスすることはできません。

535

そのような質問に対する知恵の源を調べてみましょう。Joshua BlochのEffective Java

技術的には、静的内部クラスのようなものはありません。 有効なJavaによれば、正しい用語は静的ネストクラスです。非静的な入れ子クラスは、無名クラスとローカルクラスとともに、実際には内部クラスです。

そして今引用する:

非静的ネストクラスの各インスタンスは、その包含クラスの包含インスタンスに暗黙的に関連付けられています。囲んでいるインスタンスでメソッドを呼び出すことは可能です。

静的ネストクラスは、それを囲むインスタンスにアクセスできません。それはあまりにも少ないスペースを使用します。

124
Steve McLeod

静的内部クラスと非静的内部クラスには2つの違いがあります。

  1. メンバフィールドとメソッドを宣言する場合、非静的内部クラスは静的フィールドとメソッドを持つことができません。しかし、静的内部クラスの場合、静的および非静的フィールドとメソッドを持つことができます。

  2. 非静的内部クラスのインスタンスは、それが定義されている外部クラスのオブジェクトの参照を使用して作成されます。つまり、それは外側のインスタンスを含みます。しかし、静的内部クラスのインスタンスは、外部クラスを参照せずに作成されます。つまり、包含内部インスタンスがありません。

この例を参照

class A
{
    class B
    {
        // static int x; not allowed here
    }

    static class C
    {
        static int x; // allowed here
    }
}

class Test
{
    public static void main(String… str)
    {
        A a = new A();

        // Non-Static Inner Class
        // Requires enclosing instance
        A.B obj1 = a.new B(); 

        // Static Inner Class
        // No need for reference of object to the outer class
        A.C obj2 = new A.C(); 
    }
}
63
user918477
  1. 静的内部クラスは、それを囲むクラスの非静的メンバーにアクセスできません。オブジェクトを作成せずに値を取得する手続き型スタイルと同じように、それを囲むクラスの静的メンバー(インスタンスフィールドとメソッド)に直接アクセスできます。

  2. 静的内部クラスは、静的メンバーと非静的メンバーの両方を宣言できます。静的メソッドは、メインクラスの静的メンバーにアクセスできます。ただし、静的でない内部クラスメンバにはアクセスできません。非静的内部クラスのメンバにアクセスするには、非静的内部クラスのオブジェクトを作成する必要があります。

  3. 非静的内部クラスは、静的フィールドおよび静的メソッドを宣言することはできません。静的型または最上位型のいずれかで宣言する必要があります。そうすると「静的フィールドは静的または最上位の型でのみ宣言される」と言ってこのエラーになるでしょう。

  4. 非静的内部クラスは、囲むクラスの静的メンバーと非静的メンバーの両方に、手続き型の値を取得する方法でアクセスできますが、静的内部クラスのメンバーにはアクセスできません。

  5. 囲んでいるクラスは、内部クラスのオブジェクトを作成するまで、内部クラスのメンバーにアクセスできません。メインクラスが非静的クラスのメンバにアクセスする場合は、非静的内部クラスのオブジェクトを作成できます。

  6. メインクラスが静的内部クラスのメンバにアクセスする場合、2つのケースがあります。

    • ケース1:静的メンバーの場合は、静的内部クラスのクラス名を使用できます
    • ケース2:非静的メンバーの場合は、静的内部クラスのインスタンスを作成できます。
12

入れ子になったクラスについて議論しています...

違いは、同様に静的である入れ子のクラス宣言は、外側のクラスの外側でインスタンス化できるということです。

入れ子になったクラス宣言が静的ではない場合、Javaはそれを囲むクラス以外ではインスタンス化できません。内部クラスから作成されたオブジェクトは外部クラスから作成されたオブジェクトにリンクされているので、内部クラスは外部のフィールドを参照できます。

しかしそれが静的であれば、リンクは存在せず、外側のフィールドにアクセスすることはできません(他のオブジェクトのような通常の参照による場合を除く)したがって、ネストしたクラスを単独でインスタンス化します。

10
DigitalRoss

静的内部クラス:静的メンバーと非静的メンバーを宣言できますが、その親クラスの静的メンバーにのみアクセスできます。

非静的内部クラス:非静的メンバーのみを宣言できますが、その親クラスの静的メンバーと非静的メンバーにはアクセスできます。

3
Vijay Kumar

内部クラスは静的にはできないので、私はあなたの質問を「静的と非静的の入れ子クラスの違いは何ですか?」と述べます。

uがここで言ったように、内部クラスは静的にはできません...私は静的に与えられている以下のコードを見つけました....理由?またはどちらが正しいです....

はい、静的ネストされた型のセマンティクスには、そうすることを妨げるものは何もありません。このスニペットはうまくいきます。

    public class MultipleInner {
        static class Inner {
        }   
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Inner();
        }
    }
}

これはこのWebサイトに投稿されたコードです...

--->静的な入れ子クラスを複数回インスタンス化することはできますか?

答えは--->

さて、もちろんネストされた型はそれ自身のインスタンス制御(例えば、プライベートコンストラクタ、シングルトンパターンなど)を行うことができますが、それはそれがネストされた型であるという事実とは関係ありません。また、入れ子になった型が静的列挙型の場合、もちろんインスタンス化することはできません。

しかし、一般的には、はい、静的ネスト型は複数回インスタンス化できます。

技術的には、静的な入れ子型は「内部」型ではありません。

3
kathir

静的ネストクラスは、他の最上位クラスと同じように、その外部クラス(および他のクラス)のインスタンスメンバーと対話します。実際には、静的にネストされたクラスは、パッケージ化の便宜のために、動作的には別のトップレベルクラスにネストされているトップレベルクラスです。

2
Emil