2009-08-18 5 views
16

numaralı döndürülen joker karakter jenerikleri, genellikle bağımsız değişkenleri (ve örneğin C# 'nun tersine dönüş türünde bile) temel alan jenerikleri bulabilir.Dönüş türü

Tipik bir örnek:

Pair<String, String> pair = Pair.of("Hello", "World"); 

yöntem of sadece şuna benzer::

Sadece değerlerin bir çift depolar ve şu şekilde kullanılabilecek bir genel sınıf Pair<T1, T2> var
public static <T1, T2> Pair<T1, T2> of(T1 first, T2 second) { 
    return new Pair<T1, T2>(first, second); 
} 

Çok güzel.

Pair<Class<?>, String> pair = Pair.of((Class<?>) List.class, "hello"); 

kod sağlanan aşağıdaki hata (başarısız olur (List.class doğru türde yapmak için açık döküm dikkat edin.): Ancak, bu artık joker gerektirir aşağıdaki kullanım örneği için çalışıyor) Eclipse tarafından:

Tip uyumsuzluğu: TestClass.Pair<Class<?>,String>

için TestClass.Pair<Class<capture#1-of ?>,String> dönüştüğünde olamaz

Ancak açıkça çağıran yapıcı hala beklendiği gibi çalışır:

Pair<Class<?>, String> pair = 
    new Pair<Class<?>, String>((Class<?>) List.class, "hello"); 

birisi bu davranış açıklayabilir misiniz? Tasarım gereği mi? istediği mu? Yanlış bir şey mi yapıyorum yoksa derleyicide tasarım/hatada bir hataya rastladım mı?

Yabani tahminim: nasılsa tip bir Class<List> yapma ve böylece (Pair<Class<?>, String> den Pair<Class<List>, String> kadar) dönüşümü başarısız, joker anında derleyici tarafından doldurulur ima görünüyor “? 1-yakalanması #” . Bu doğru mu? Bu etrafında çalışmak için bir yolu var mı? Yapıcı çalışır

public final class Pair<T1, T2> { 
    public final T1 first; 
    public final T2 second; 

    public Pair(T1 first, T2 second) { 
     this.first = first; 
     this.second = second; 
    } 

    public static <T1, T2> Pair<T1, T2> of(T1 first, T2 second) { 
     return new Pair<T1, T2>(first, second); 
    } 
} 
+0

"nin" imzasını görür bir Çifti Sınıfını genişletir,? Sınıf > türünü genişletir. Son sınıflar için, uzantıları azaltmak için yeterince akıllı gözüküyor, bu yüzden String'de şikayet etmiyor. – Zed

+0

Hmmm, ilginç. Beni buraya bağladığın için teşekkürler. – jjnguy

+0

Şimdi java8'de çalışıyor. Hedef türü inferene de başvurulur. – ZhongYu

cevap

13

nedeni açıkça tür parametreleri belirterek konum şudur:

tamlık hatırına

, burada Pair sınıfın basitleştirilmiş bir versiyonudur.

Pair<Class<?>, String> pair = Pair.<Class<?>, String>of(List.class, "hello"); 

Tabii ki, bütün nedeni ilk etapta statik bir metod sadece hiç kurucular ile çalışmıyor tip çıkarsama (almak muhtemelen vardır: Bunu yaparsanız statik yöntem de çalışacak herşey).

Burada (derlediğiniz gibi) sorun, derleyicinin capture conversion gerçekleştirmesidir. Bu [§15.12.2.6 of the JLS] sonucu olduğuna inanıyorum:

  • şöyle seçilen yöntemin sonucu türü belirlenir:
    • çağrılan yöntemi geçersiz, bir dönüş türü ile beyan edilirse o zaman sonuç geçersizdir.
    • Aksi takdirde, yönteminin uygulanabilmesi için denetimsiz dönüşüm gerekiyorsa, sonuç türü, yöntemin beyan edilen dönüş türünün silinmesidir (§4.6).
    • Aksi takdirde, yöntemi çağrılan eğer Fi resmen tip parametreleri yöntemi olalım Ai argümanlar yöntem çağırma bilgilerin tahmin fiili tip olalım, ve R olalım, 1in daha sonra, geneldir bildirilen yöntemin dönüş türü çağrılır. Sonuç tip R [: = A1, ..., Fn: = bir F1] yakalama dönüşüm (§5.1.10) uygulanarak elde edilir.
    • Aksi takdirde, sonuç tipi yöntem bildiriminde verilen tipine yakalama dönüşümü (§5.1.10) uygulanarak elde edilir. Eğer gerçekten çıkarım istiyorsanız

, olası bir geçici çözüm böyle bir şey yapmaktır:

Pair<? extends Class<?>, String> pair = Pair.of(List.class, "hello"); 

değişken pair daha geniş bir tip olacak ve bu biraz demek değişkenin türünde daha fazla yazarak, ancak en azından artık yöntem çağrısı yapmak zorunda kalmazsınız. Bu dönüştürücü gibi görünüyor

+0

Çok teşekkürler. Yine de, geçici çözümün çekirdeği daha da kafa karıştırıcı hale getirip getirmediğini düşünüyorum. Şu an olduğu gibi bırakacağım. –