126

Java では、ネストされたクラスはどちらでもかまいstaticません。それらが である場合static、それらはそれを含むインスタンスのポインタへの参照を含みません (それらはもはや内部クラスとも呼ばれず、ネストされたクラスと呼ばれます)。

static参照が必要ないときにネストされたクラスを作成するのを忘れると、ガベージ コレクションやエスケープ解析で問題が発生する可能性があります。

匿名の内部クラスstaticも作成できますか? それとも、コンパイラはこれを自動的に把握しますか (サブクラスが存在できないため、可能でした)?

たとえば、匿名のコンパレータを作成すると、外部への参照はほとんど必要ありません。

  Collections.sort(list, new Comparator<String>(){
       int compare(String a, String b){
          return a.toUpperCase().compareTo(b.toUpperCase());
       }
  }
4

6 に答える 6

139

いいえ、できません。また、コンパイラはそれを理解できません。これが、FindBugsが暗黙の参照staticを使用しない場合、匿名の内部クラスを名前付きのネストされたクラスに変更することを常に提案する理由です。this

編集: Tom Hawtin-タックラインは、匿名クラスが静的コンテキスト(mainメソッドなど)で作成された場合、匿名クラスは実際にはであると述べていstaticます。しかし、JLSは同意しません

匿名クラスは決してありませんabstract(§8.1.1.1)。匿名クラスは常に内部クラスです(§8.1.3)。それは決してありませんstatic(§8.1.1、§8.5.1)。匿名クラスは常に暗黙的にfinal行われます(§8.1.1.2)。

Roedy GreenのJava用語集によると、静的コンテキストで匿名クラスが許可されるという事実は、実装に依存します。

あなたがあなたのコードを維持している人々を困惑させたいのなら、言語仕様が匿名クラスは決してそうではないと言っているとしても、wagsはinitコードとメソッドjavac.exe内で匿名クラスを許可することを発見しました。もちろん、これらの匿名クラスは、オブジェクトのインスタンスフィールドにアクセスできません。これを行うことはお勧めしません。この機能はいつでもプルできます。staticstaticstatic

編集2: JLSは実際には§15.9.2でより明示的に静的コンテキストをカバーしています:

Cをインスタンス化されるクラスとし、iを作成されるインスタンスとします。Cが内部クラスである場合、はすぐに囲むインスタンスを持っている可能性があります。iのすぐに囲まれたインスタンス(§8.1.3)は次のように決定されます。

  • Cが匿名クラスの場合、次のようになります 。
    • クラスインスタンス作成式が静的コンテキスト(§8.1.3)で発生する場合、iにはすぐにインスタンスを囲むことはありません。
    • それ以外の場合、 iのすぐに囲むインスタンスはですthis

staticしたがって、静的コンテキストの匿名クラスは、技術的にはクラスではありませんが、それを囲むクラスへの参照を保持しないという点で、ネストされたクラスとほぼ同等staticです。

于 2009-04-17T00:43:56.220 に答える
15

すこし。静的メソッドで作成された匿名内部クラスは、外部 this のソースがないため、明らかに効果的に静的になります。

静的コンテキストの内部クラスと静的なネストされたクラスの間には、いくつかの技術的な違いがあります。興味のある方は、JLS 3rd Ed をお読みください。

于 2009-04-17T10:18:59.553 に答える
6

内部クラスを静的にすることはできません。静的にネストされたクラスは内部クラスではありません。Javaチュートリアルでは、ここでそれについて説明しています

于 2009-04-17T00:43:15.660 に答える
0

匿名内部クラスは決して静的ではありません (静的メソッドまたは非 final 静的フィールドを宣言することはできません) が、静的コンテキスト (静的メソッドまたは静的フィールド) で定義されている場合、それらはできないという意味で静的として動作します。外側のクラスの非静的 (つまりインスタンス) メンバーにアクセスする (静的コンテキストからの他のすべてのものと同様)

于 2016-02-02T11:19:59.427 に答える
-3

静的メソッド内で呼び出すことにより、匿名の内部クラスを静的にすることに注意してください。

これは実際には参照を削除しません。これをテストするには、匿名クラスをシリアル化して、囲んでいるクラスをシリアル化できないようにします。

于 2011-03-21T00:51:06.577 に答える