web-dev-qa-db-ja.com

Javaで内部クラスを静的として作成する利点は何ですか?

Javaクラスに内部クラスがあります。

enter image description here

バグを見つける を実行すると、静的にすることを推奨(警告)します。

enter image description here

この警告の意味は何ですか?内部クラスを静的にする利点は何ですか?

28
prosseek

入れ子になったクラスが外側のクラスの変数にアクセスしない場合は、静的にすることができます。これの利点は、ネストされたクラスを使用するために外側のクラスを囲むインスタンスが必要ないことです。

25
Jeff Storey

内部クラスには、デフォルトで外部クラスのオブジェクトへの暗黙的な参照があります。これのオブジェクトを外部クラスのコードからインスタンス化する場合、これはすべて自動的に行われます。それ以外の場合は、オブジェクトを自分で提供する必要があります。

静的内部クラスにはこれはありません。

つまり、外部クラスオブジェクトのスコープ外でインスタンス化できるということです。また、内部クラスのインスタンスを「エクスポート」しても、現在のオブジェクトの収集が妨げられることはありません。

基本的に、内部クラスが外部クラスにアクセスする理由がない場合は、デフォルトで静的にする必要があります。

10
Joeri Hendrickx

非静的内部クラスには、外部クラスへの暗黙の参照があります。クラスを静的にすると、メモリとコードを節約できます。

3
kan

静的内部クラスは、意味的に単純なものです。可視性のオプションが多いことを除いて、トップレベルのクラスと同じです(たとえば、非公開にすることができます)。

非静的内部クラスを回避する重要な理由は、それらがより複雑であることです。外部クラスへの隠された参照があります(おそらく複数)。また、内部クラスのメソッドの単純な名前は、ローカル、フィールド、または外部クラスのフィールドの3つのうちの1つになりました。

その複雑さのアーティファクトは、外部クラスへの隠された参照がメモリリークにつながる可能性があることです。内部クラスがリスナーであり、静的内部クラスである可能性があるとします。リスナーが登録されている限り、リスナーは外部クラスのインスタンスへの参照を保持します。これにより、大量のメモリが保持される可能性があります。リスナーを静的にすると、外部インスタンスがガベージコレクションされる可能性があります。

2
TimK

静的内部クラスの利点:1.静的内部クラスのインスタンス化は外部クラスガイダンスに依存せず、インスタンス化のメモリオーバーヘッド2.静的内部クラスは外部クラスガイダンスを保持せず、外部クラスのコレクションに影響せず、回避するメモリリークにつながるメモリ存続時間の外部クラスの拡張

0
chao sibada

私たちはすでに良い答えを持っています、これが私の5セントです:

外部クラスのメソッドと変数を使用しながら、論理機能を分離する必要がある場合は、静的内部クラスと非静的内部クラスの両方が使用されます。両方の内部クラスは、外部クラスのプライベート変数にアクセスできます。

静的内部クラスの利点:1)静的クラスは外部クラスから静的変数にアクセスできる2)静的クラスは独立したクラスのように扱うことができる

非静的内部クラス:1)外部クラスの静的メンバーを使用できない2)独立したクラスのように処理できない

public class NestedClassDemo {
    private int a = 100;
    int b = 200;
    private static int c = 500;

    public NestedClassDemo() {
        TestInnerStatic teststat = new TestInnerStatic();
        System.out.println("const of NestedClassDemo, a is:"+a+", b is:"+b+".."+teststat.teststat_a);
    }

    public String getTask1(){
        return new TestInnerClass().getTask1();
    }

    public String getTask2(){
        return getTask1();
    }


    class TestInnerClass{
        int test_a = 10;

        TestInnerClass() {
            System.out.println("const of testinner private member of outerlcass"+a+"..."+c);
        }
        String getTask1(){
            return "task1 from inner:"+test_a+","+a;
        }
    }

    static class TestInnerStatic{
        int teststat_a = 20;

        public TestInnerStatic() {
            System.out.println("const of testinnerstat:"+teststat_a+" member of outer:"+c);
        }

        String getTask1stat(){
            return "task1 from inner stat:"+teststat_a+","+c;
        }
    }

    public static void main(String[] args){
        TestInnerStatic teststat = new TestInnerStatic();
        System.out.println(teststat.teststat_a);
        NestedClassDemo nestdemo = new NestedClassDemo();
        System.out.println(nestdemo.getTask1()+"...."+nestdemo.getTask2());
    }
}

外部から静的内部クラスと非静的内部クラスにアクセスする:

public class TestClass {
    public static void main(String[] args){
        NestedClassDemo.TestInnerClass a = new NestedClassDemo().new TestInnerClass();
        NestedClassDemo.TestInnerStatic b = new NestedClassDemo.TestInnerStatic();
    }
}

公式のJava静的内部クラスのドキュメントは https://docs.Oracle.com/javase/tutorial/Java/javaOO/nested.html にあります

0
Ramesh