2009-09-03 19 views
41

{{ ... }} bloğu aşağıdaki kodda ne anlama geliyor?Yeni Sınıf Anlamı (...) {{...}} initialization idiom

class X { 

    private Y var1; 

    private X() { 
     Z context = new Z(new SystemThreadPool()) {{ 
      var1 = new Y(); 
     }}; 
    } 

} 
+5

Sanırım çift kaşlı ayraçlar için Google'a kolay değil. –

+3

@Tom Hawtin: Bunun yerine Google'da "çift parantez" için ... –

cevap

62

Adı double curly brace initialization. (EDIT: Bağlantı kaldırıldı, archived here)

Bu, anonim bir alt sınıf oluşturduğunuz ve çift parantez içindeki kodun temel olarak bir kurucu olduğu anlamına gelir. Genellikle koleksiyonlara içerik eklemek için kullanılır çünkü temelde toplama sabitleri olanı oluşturmak için Java'nın sözdizimi biraz gariptir. Aslında sevmiyorum

List<String> list = new ArrayList<String>(); 
list.add("one"); 
list.add("two"); 
list.add("three"); 

ve bunu yapmak için tercih:

List<String> list = new ArrayList<String>() {{ 
    add("one"); 
    add("two"); 
    add("three"); 
}}; 

yerine:

Yani yapacağım

List<String> list = Arrays.asList("one", "two", "three"); 

Yani kokan Bu durumda çok anlamlı olurken, uygun bir yardımcıya sahip olmayan Haritalar için.

+0

@skaffman [JATL] (http://code.google.com/p/jatl) gibi "sıvı java" da çok yararlıdır denemeler. –

+6

Arrays.asList() işlevi java.util.Arrays.ArrayList.ArrayList'i ve sınırlı işlevselliğe sahip java.util.ArrayList'i döndürmediğini unutmayın. – Asaf

+3

Bu teknik zor ve bazı uyarılar var. Herhangi bir sebep olmaksızın kırık eşitlik() sözleşmesi veya artan bellek kullanımı ile sonuçlanabilir. Ne yaptığınızı tam olarak bilmediğiniz sürece, çift kaşlılık başlatmadan kaçınmak daha iyidir. Daha fazla bilgi için [this] (http://www.ayp-sd.blogspot.com/2012/12/double-brace-initialization-in-java.html) adresine bakın. –

11

"Dış" parantezleri anonim bir alt sınıf oluşturduğunuz anlamına gelir, ikinci parantezler nesne başlatıcısıdır. Başlatıcı, sınıf yapıcısından önce çalıştırılır, ancak herhangi bir super çağrısından sonra (ve dolayısıyla herhangi bir üst sınıf başlatıcıdan sonra). Başlatıcıları, anonim olmayan sınıflarda da kullanabilirsiniz, bu da birbirinizi arayaamayan birkaç kurucuya sahipseniz veya olağan alan başlatıcılarının izin verdiğinden daha karmaşık başlatma gerektiren alanlara sahipseniz, final alanlarını başlatmak için uygun bir yoldur. başlatıcı bir kontrol istisna Eğer tüm kurucular bunu atabilir ilan etmeli,

class X extends Y{ 
    private final int lulz; 

    private static boolean someCondition(){...} 
    private static boolean danger() throws SomeException { ... } 
    { // initalizer -- might throw SomeException! 
     lulz = someCondition()? danger() : 0; 
    } 
    public X(A a) throws SomeException { super(a); } 
    public X(B b) throws SomeException { super(b); } 
} 

:

class X extends Y{ 
    private final int lulz; 

    private static boolean someCondition(){...} 
    private static boolean danger() throws SomeException { ... } 
    public X(A a) throws SomeException { 
     super(a); 
     lulz = someCondition()? danger() : 0; 
    } 
    public X(B b) throws SomeException { 
     super(b); 
     lulz = someCondition()? danger() : 0; 
    } 
} 

Bu şekilde tekrar yazılabilir:

bu sınıfı düşünün.

4

Bir anonymous class oluşturup bu gibi class Instance initialize r deyim kullanıyor:

önceki yanıtlarında belirtildiği gibi
class X { 
    private Y var1; 

    private X() { 
     Z context = new Z(
       new SystemThreadPool()) { 
        {      // This is the initialize idiom 
         var1 = new Y();  // 
        }      // 
       } 
     ); // BTW you are missing ")" 
    } 
} 
1

, çift küme ayracı başlatma doğrudur.

Java'da Örnek Üyeleri'u Başlatma için belirli bir teknik kullanır. Bir sınıf tanımlayıcısından herhangi biri etkinleştirildiğinde çalışacak paylaşılan bir kod bloğu olan sınıf tanımını tanımlamanın kısa yoludur.

Bağlantı hakkında daha geniş kapsamlı bir görünüm için official Java documentations numaralı bağlantıyı ekliyorum.Gönderen

documentation:

örnek değişkenler için

Initializer bloklar sadece statik başlatıcı bloklar gibi ancak static anahtar sözcüğü olmadan bak:

{

// whatever code is needed for initialization goes here 

}

Java derleyici, başlatıcı bloklarını int kopyalar o her kurucu. Bu nedenle, bu yaklaşım, çoklu kurucular arasında bir kod bloğunu paylaşmak için kullanılabilir.