2013-04-22 2 views
19

私はJavaクラスに内部クラスを持っています。内部クラスをJavaで静的にする利点は何ですか?

enter image description here

私はfind bugsを実行すると、それは静的にする(警告する)をお勧めします。

enter image description here

この警告のポイントは何ですか?内部クラスを静的にする利点は何ですか?

+0

可能重複で見つけることができます(http://stackoverflow.com/questions/70324/java-inner-クラスと静的ネストされたクラス) – andyb

+0

リンクされた質問は重複ではありません*内部クラスを静的にする利点や欠点を示すものではありません。 – Perception

+0

[Javaの静的なネストされたクラス、なぜ?](http://stackoverflow.com/questions/253492/static-nested-class-in-java-why) – fglez

答えて

19

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

+0

+1私はこの問題に直面して、 Mana Potionは私のPotionクラスにありますが、静的であると宣言するのを忘れると、新しいManaPotionを宣言することは不可能になりました。 – arynaq

+1

@arynaq - 継承は、 'ManaPotion'が' Potion'の内部クラスでなければならないという強力な指標です。よい正の例は 'Map.Entry'インスタンスを使ってエントリを保持する' Map'です。 'Potion'は' Potion.ManaPotion'を使いますか?これは、静的な内部クラスに対しても適用されます。 –

+0

実際、テストのために、私がネストされたクラスを使う唯一の時間です。 – arynaq

2

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

7

内部クラスは、デフォルトで外部クラスのオブジェクトへの暗黙の参照を持ちます。このクラスのオブジェクトを外部クラスのコードからインスタンス化すると、これがすべて完了します。そうしないと、オブジェクトを自分で提供する必要があります。

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

つまり、外部クラスオブジェクトのスコープ外でインスタンス化することができます。また、内部クラスのインスタンスを「エクスポート」すると、現在のオブジェクトが収集されることを防ぎません。

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

+0

私は基本ルールが大好きです。それはあなたが定義したものです。 – roottraveller

2

静的内部クラスは、意味的に簡単なものです。これはトップレベルのクラスと似ていますが、可視性を高めるオプションが他にもある(例:非公開にすることができます)。

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

この複雑さのアーティファクトは、外部クラスへの隠れた参照がメモリリークを引き起こす可能性があることです。内部クラスがリスナーであり、静的内部クラスである可能性があるとします。リスナーが登録されている限り、外部クラスのインスタンスへの参照が保持され、大量のメモリが保持される可能性があります。リスナーを静的にすることで、外部インスタンスをガーベッジ・コレクションにすることができます。私たちは外部クラスのメソッドと変数を使用して、まだ論理的機能を分離する必要がある場合、内部クラスが使用されている

静的および非静的両方:我々はすでにここに、良い答えを持っている

0

は私の5セントです。両方の内部クラスは、外部クラスのプライベート変数にアクセスできます。静的内部クラスの

利点: 1)静的クラスは、静的クラスは独立クラス

非静的内部クラスのように処理することができる)、外側クラス 2から静的変数にアクセスすることができる: 1)を使用することができません

0123:外部クラス 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ドキュメントは、[Javaの内部クラスと静的ネストされたクラス]のhttps://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

関連する問題