2013-02-15 15 views
12

İki kurucudan biri kullanılarak başlatılabilen çok sayıda son üyeye sahip bir sınıfa sahibim. Kurucular, üçüncü bir kurucuda depolanan bazı kodları paylaşırlar. Variable 'two' might not have been initialized. Birisi muhtemelen Sınıfım içinden birinci yapıcı diyebiliriz ve sonra yeni bir nesne yok "iki" alan kümesi olurdu:Java'da son alanları başlangıç ​​durumuna getirme

// SubTypeOne and SubTypeTwo both extend SuperType 

public class MyClass { 
    private final SomeType one; 
    private final SuperType two; 


    private MyClass(SomeType commonArg) { 
     one = commonArg; 
    } 

    public MyClass(SomeType commonArg, int intIn) { 
     this(commonArg); 

     two = new SubTypeOne(intIn); 
    } 

    public MyClass(SomeType commonArg, String stringIn) { 
     this(commonArg); 

     two = new SubTypeTwo(stringIn); 
    } 

sorun bu kod derlemek olmamasıdır.

Bu durumda, kurucular arasında kod paylaşmanın tercih edilen yolu nedir? Normalde bir yardımcı yöntem kullanırdım, ancak paylaşılan kod sadece bir kurucudan yapılabilecek son değişkenleri ayarlayabilmelidir.

+3

Bu iki * özdeş * kurucular (aynı parametreleri, aynı gövde) sahip olarak şu anda sorunuzu anlamak zordur. Daha fazla temsilci bulabilir misin? –

+2

İlk kurucuda, iki başlatılmamış. –

+5

@Jon Skeet - Yeniden bak, parametre tipleri farklı. –

cevap

16

Bu nasıl? Eğer MyClass(SomeType oneIn) denilen olsaydı, two başlatılmadı için bu hatayı olsun

public class MyClass { 

    private final SomeType one; 
    private final SuperType two; 

    public MyClass (SomeType commonArg, int intIn) { 
     this(commonArg, new SubTypeOne(intIn)); 
    } 

    public MyClass (SomeType commonArg, String stringIn) { 
     this(commonArg, new SubTypeTwo(stringIn)); 
    } 

    private MyClass (SomeType commonArg, SuperType twoIn) { 
     one = commonArg; 
     two = twoIn; 
    } 
} 
+0

Ah, bu benim hatam. Örneğimi biraz karıştırdım; Şimdi yazdığım yolu kontrol et. Ancak, bana her iki kurucuyu SuperType alan ve arayanın aramadan önce SuperType nesnesini gerçekten oluşturmasını sağlayan bir fikir verdiniz. Aramanın gerçekleştiği yerde SuperType'ın görünmemesini tercih ederim, ancak düşünebileceğim en iyisi budur. –

+0

Kolay anlaşılır. Buna ne dersin? "SuperType" alt sınıfının kullanılmasına izin vermez, çoğaltmayı önler ve her zaman değişkenlere atar. Not, belirsizliği önlemek için "null" üzerindeki döküm. https://gist.github.com/stickyd/4965120 –

2

Yapmanız gereken tek şey "iki" nin başlatıldığından emin olmanızdır. İlk Yapıcıda, sadece ekleyin:

two = null; 

sadece ilk kurucu olarak tanımladığı olay bunu vermek istiyorum bazı diğer değer olmadığı sürece.

+2

Ama iki 'final'. –

+0

Bir son değişkeni null olarak başlatabilirsiniz. Sadece bir şeye * başlaması gerekiyor. Eğer null olmayan bir değere sahip olmak istiyorsanız, o zaman diğer kuruculardan birini çağırmalısınız. Bu, Sticky'nin cevabıyla aynı sonucu verdi. – Halogen

+1

Ancak, ilk yapıcıda 'two' öğesini null olarak ayarlarsanız, o zaman zaten ayarlanmış olduğundan gerçek değerini diğer yapıcılara ayarlayamamamdır. –

3

Her kurucuda tüm son değişkenleri başlattığınızdan emin olmalısınız. Yapmam gereken şey, tüm değişkenleri ilklendiren ve diğer tüm kurucunun, null'dan geçerek veya bir değer verilmedikleri bir alan varsa, bazı varsayılan değerlere sahip olan bir kurucuya sahip olmasıdır.

Örnek:

public class MyClass { 
    private final SomeType one; 
    private final SuperType two; 

    //constructor that initializes all variables 
    public MyClas(SomeType _one, SuperType _two) { 
     one = _one; 
     two = _two; 
    } 

    private MyClass(SomeType _one) { 
     this(_one, null); 
    } 

    public MyClass(SomeType _one, SubTypeOne _two) { 
     this(_one, _two); 
    } 

    public MyClass(SomeType _one, SubTypeTwo _two) { 
     this(_one, _two); 
    } 
} 
İlgili konular