2015-01-02 10 views
13

です。なぜ匿名クラスは、私は、Javaの匿名クラスが何であるかについての誤解を持っている静的コンテキストで有効

public static void main (String[] args) throws java.lang.Exception 
{ 
    B b = new B(){ }; 
    System.out.println(b.b); 
} 

interface B{ int b = 1; } 

DEMO

なぜコードはコンパイルん:次の簡単な例を考えてみましょうか? JLS, chapt 15さんのコメント:

匿名クラスは常に内部クラス(8.1.3)です。それは 静的

ことはありません。しかしJLS, chapt 8

内部クラスは、明示的または暗黙的に 静的宣言されていないネストされたクラスです。

だから、匿名クラスは内部クラスです。しかし、私たちは静的なコンテキストでそれらを使用します。なぜここで正しいのですか?

+0

'B b = new B(){};'は匿名クラスではありません。静的コンテキストで*使用されているため動作しますが、内部クラス自体が静的であることを宣言しています。 –

+0

@Shywimしたがって、 'new B(){}'によって作成されたオブジェクトはどのような型ですか? –

答えて

7

非静的匿名クラスを作成することを証明していますここに。

静的コンテキストと非静的コンテキストで作成された匿名クラスとの違いは、それが親インスタンスを持っているかどうかです::

意味のは、staticとして宣言されているものを見てみましょう、と静的コンテキストで作成

Cは、その後、匿名クラスである場合:

  • クラスインスタンス生成式が静的コンテキストで発生した場合、私は直ちに取り囲むインスタンスを有していません。

  • それ以外の場合は、iをすぐに囲むインスタンスがこれになります。静的に宣言され

ネストされたクラスは、静的メンバを許可:

内部クラスは、明示的または暗黙的に静的宣言されていないネストされたクラスです。

内部クラスではないネストされたクラスは、Javaプログラミング 言語の通常の規則に従って、静的メンバー を自由に宣言できます。 「暗黙的には、staticとして宣言」で、ネストされたクラスを言って

、それはインタフェース内のクラスのようなものを指し:

インタフェースのメンバクラスが(§9.5)が暗黙的に静的なことはありません は内部クラスとみなされます。

匿名クラスは(どちらも明示的にキーワードを指定して、または暗黙的なインターフェースの内側にあるものとして)静的に宣言されていない、ので、静的メンバの宣言を許可していません。ただし、静的コンテキスト内で作成することができます。つまり、インスタンスを囲むインスタンスを参照しません。

匿名クラスはstaticと宣言されていないため、質問の両方の引用符は一貫しています。

3

あなたはそれが匿名クラスと呼ばれていますので、クラスに名前がないインタフェースBを実装するクラスを作成し、この文では

匿名内部クラス間を区別する必要があります。 javacコンパイルは、ルールYOURCLASS $ 1.class(1 YOURCLASSで匿名クラスの数に基づいて、連番、である。

B b = new B(){ }; 

new B(){ }によって作成されたクラスとして宣言することはできません命名以下でクラスファイルを作成します。静的(「匿名クラスは常に内部クラス(8.1.3)であり、それは決して静的である」)。。

静的ネストされたクラスの例

class YourClass { 
    static class StaticNestedClass { 
    } 
} 

非静的ネストされたクラスの例

class YourClass { 
    // An inner class is a nested class that is not explicitly or implicitly declared static. 
    class InnerClass { 
    } 
} 

ネストされたクラスには、静的と非静的の2種類があります。静的と宣言されたネストされたクラスは、いわゆるstatic nested classesですが、静的なものとして宣言されていないネストされたクラスは、いわゆるinner classesです。

+1

私たちはあなたの理解の代わりにJLSを引用している回答を探しています。 – nhahtdh

+2

これは内部クラスの基本的な紹介ですが、質問にはまったく対処しません。 – chrylis

1

Bは、内側インターフェースあります。したがって、Bは暗黙的に静的であり、静的コンテキストでBを参照することができます。 (JLS 8.5.1より:メンバインターフェイスは暗黙的に静的です(§9.1.1)。

しかし、Bを介して作成匿名クラスは静的ではなく、非静的コンテキストから参照する場合は、あなたが外側のオブジェクトへのアクセスを得ることができます:あなたの例では

public class Main{ 

    public static void main(String[] args) throws java.lang.Exception { 
     B b = new B() { 

      @Override 
      public Ess3 getParent() { 
       //return Ess3.this; ERROR : non static variable cannot be referenced from static context 
       return null; 
      } 
     }; 
     System.out.println(b.b); 
    } 

    interface B { 

     int b = 1; 
     Ess3 getParent(); 
    } 

    /* a non static method */ 
    void foo() { 
     B b = new B() { 

      @Override 
      public Ess3 getParent() { 
       return Ess3.this; // this anonymous class is not static 
      } 

     }; 

    } 
} 

を、あなたはあなたを考えることができあなたはそれを作成したので、静的な匿名の内部クラスを作成:静的コンテキスト内の静的ネストされたインタフェースから

  • - ので、外側のオブジェクトへのアクセスがないと

しかし、非静的コンテキストで同じ宣言静的ネストされたインタフェースは、クラスがstaticと宣言されることなく、静的コンテキストで作成することができ、これは何が起こっているかである

+0

あなたの主張を強化するためにJLSから引用してください。 – nhahtdh

+0

@nhahtdh:私はOPが既にJLSの関連部分を引用していると思ったが、私は別の答えでそれを読んだ。編集された投稿 –

関連する問題