2009-07-08 6 views
14

残念ながら、私はJavaを約5年間コード化していません。次のコードがどのように、なぜ、なぜ動作しているのか、私は絶対に思い出せません。このコンストラクタコールは、次の二重ブレースとは何ですか?

私は同じような例を見つけて、これを壊しました。強調は、コメントの下にある部分に重点を置いています。コンストラクタの表記に二重括弧で囲まれたブロックが続くわけではありません。残念ながら、私はJavaのドキュメントやGoogleを使って何かを見つけることができません(私はどんな言葉をGoogleに送りますか?)。だからここ

package syntaxtest; 

public class Main { 

    public static void main(String[] args) { 

     // What kind of notation is this? 
     MyTest tester = new MyTest() {{ 
      setName("John Johnson"); 
     }}; 

     System.out.println(tester.getName()); 
    } 
} 


class MyTest { 
    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

は私の質問は以下のとおりです。

  1. はどのようにこの表記/構文は呼ばれているのですか?
  2. どこでドキュメントを読むことができますか?

誰かが最初の質問に対する答えを私に提供できる場合、私は自分自身で2番目の質問に答えることができます。

出力を確認するには:John Johnson;)しかし、私はなぜそれが動作しているのかわかりません。

+0

と同じです。それが何であるかを知ったら、それは明らかです。 –

+0

私はまあまあ、このきちんとしたトリックを見ましたが、私はまたそれを使って物を壊すことは簡単だった/非常に信頼性がありませんでしたと言ってかなりの免責事項を見ました。もし私がそれを使ってみようとすれば、A)私はそれをすべての人に説明してからコードを見なければならないと思うだろうし、B)いくつかの研究をしなければならないこのパターンを使用することのすべての意味を理解する。 –

+0

すばやく役立つ返信いただきありがとうございます。 – klekker

答えて

20

これはdouble brace initializationとして知られている:最初のブレース新しい AnonymousInnerClassを作成

、第 は匿名内部 クラスがインスタンス化されるときに実行されたインスタンスの初期化ブロック を宣言する。 「静的初期化子が」 が キーワード静的 前に配置され、関連する概念です - それは がインスタンススコープクラスの 内で宣言されているため 初期化子ブロックのこのタイプは、正式に、 「インスタンス初期化子」と呼ばれています初期化ブロックは、任意 メソッド、フィールド、最終変数 利用可能でを使用することができ、ブロックを開始し、かつ をできるだけ早く クラスローダが( http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.6に指定) クラスをロード完了するクラスレベルで実行される ブレース範囲が含まれていますが、 コンストラクタの前に イニシャライザが実行されていることに注意してください。

匿名サブクラスを作成するため、これは最終的な クラスでのみ機能します。

14

レッツ・レイアウト少し異なるコードは:あなたはここを参照してください何

MyTest tester = new MyTest() { 
    { 
    setName("John Johnson"); 
    } 
}; 

ダブルブレースの初期化と呼ばれています。クラスMyTestの匿名の内部サブクラスと、イニシャライザブロックがあります。イニシャライザブロックは、オブジェクトの構築時に実行されるコードを含むブロックです。

通常、コンストラクタにそのようなコードを入れますが、匿名の内部クラスはコンストラクタを持つことができないため、コードが実行されることを保証する唯一の方法です。

これは、これを行うにはちょっと醜いと言われています。より良い方法があります。しかし、私は不変のマップを作成するには、通常、次のイディオムで、時々それを自分自身を使用してください:

final Map<String, Integer> textToInt = Collections.unmodifiableMap(new HashMap<String, Integer>() {{ 
    put("one", 1); 
    put("two", 2); 
    // etc 
}}); 

、新しいマップを作成し、それを上書きし、初期化子ブロックでそれにいくつかの値を追加し、それをラップし、どの変更不可能な地図で表示されます。

-5
MyTest tester = new MyTest() {{ 
    setName("John Johnson"); 
}}; 

私が最初に私が起こっていたことを実現する前に、しばらくの間、それを見ていたユーズネット上でそれを見たとき

MyTest tester = new MyTest(); 
tester.setName("John Johnson"); 
+3

これは同じではありません。その結果は同じクラスではありません。 MyTestのインスタンスが作成されます。もう一方は、MyTestの匿名サブクラスのインスタンスを作成します。 equalsメソッドが次のようになっている場合: public boolean equals(Object other){ if(other.class!= MyTest.class){return false; } //もう少しチェックしてください... } それでは、それらを同じと見なすことはできません。 –

+3

@mangst私は、彼らが「ほとんどの目的のために機能性をもっている」と言わなければならないと思います。あなたはここでちょっとしたペナントでなければなりません - エンジニアとすべての人の本質... –

関連する問題