2013-09-02 21 views
5

Bu Koleksiyonları (bir kısmını) yöntemini kopya geçerli:Collections.copy'de genel alt tür ve joker karakterler nasıl çalışır?

public static <T> void copy(List<? super T> dst, List<? extends T> src) { 
    for (int i = 0; i < src.size(); i++) { 
    dst.set(i, src.get(i)); 
    } 
} 

4 örnek çağrı vardır:

List<Object> objs = Arrays.<Object>asList(2, 3.14, "four"); 
List<Integer> ints = Arrays.asList(5, 6); 

1. Collections.copy(objs, ints); 
2. Collections.<Object>copy(objs, ints); 
3. Collections.<Number>copy(objs, ints); 
4. Collections.<Integer>copy(objs, ints); 

Nasıl yukarıdaki arama çalışmaları? sadece aramaları zaman izin olarak

Biz de birkaç olası imzalar

1. public static <T> void copy(List<T> dst, List<T> src) 
2. public static <T> void copy(List<T> dst, List<? extends T> src) 
3. public static <T> void copy(List<? super T> dst, List<T> src) 
4. public static <T> void copy(List<? super T> dst, List<? extends T> src) 

Yukarıdaki örnek çağrıları için

ile yöntemini olduğuna dair karar,

  • Bunlardan ilki, çok kısıtlayıcı hedef ve kaynağın tam olarak aynı türü var. (Understood). tür parametre tipi parametresi son imza her üç tür parametreleri-ie için çalışır

  • , Nesne Tamsayı

    olduğu zaman üçüncü imza çalışır

  • Nesne olduğu zaman

  • ikinci imza işleri , Numara ve Tamsayı.

ikinci, üçüncü ve son imzalar da açıklayınız?

kalan üç örtülü tip parametreleri kullanabilirsiniz aramalar için eşdeğerdir, ancak açık tip parametreler için farklıdır.

Yukarıdaki ifadenin anlamı nedir?

cevap

5

İmzanızın her birini tek tek ele alalım. İlk argüman olarak List<Object> geçiyoruz olarak

1. public static <T> void copy(List<T> dst, List<? extends T> src) 

müstehcen tipi parametresi olmadan bu yöntemi çağırmak durumunda

, tür parametresi Object olarak anlaşılmaktadır edilecektir. Ve sonra List<? extends Object> bir Integer kabul edebilir. Bir List<Integer> List<? extends Number> geçmek mümkün olsa da açık tip argüman Number ile çağırmak durumunda jenerik değişmez olarak

Ancak, aynı, List<Object> ve List<Number> için doğru değildir. Eğer List<T> için List<Integer> olarak 2 argüman geçiyoruz olarak örtülü tip parametresi için yine

2. public static <T> void copy(List<? super T> dst, List<T> src) 

, T, Integer olarak anlaşılmaktadır edilecektir. Ve sonra List<Object>, List<? super Integer> için geçerli bir alternatiftir.

müstehcen tip argüman Number ile yöntemini çağırmak durumunda

, sen List<Object> olarak 1 argüman geçebilir, ancak List<Integer> olarak 2 argüman geçemez. Yukarıda açıklanan aynı sebepten dolayı.

3. public static <T> void copy(List<? super T> dst, List<? extends T> src) 

Şimdi, bu yöntem imzası her tür için çalışacaktır. Türetilen parametre türü için, dst, T örneğinin müşterisi, src ise T örneğinin üreticisidir. Örneğin, açık tip argüman Number ile çağırırsanız,List<? super Number>'a dönüştürülebilir olarak yakalanabilir, benzer şekilde List<Integer>List<? extends Number>'a dönüştürülebilir. Yani, her iki argüman da geçerli ikame.

Bu nedenle, 3 durumda, derleyici açıkça vermezseniz, derleyici, tür parametrelerini doğru şekilde tahmin edebilir. Ama sebebi varlık için buraya 4 imza kullanmalısınız - bu alt sınır kullanmalıdır böylece

  • dst, T örneğinin tüketici ve
  • srcT örneğinin yapımcı, bu yüzden Üst sınırları kullanmalı.

İlgili Mesaj:

Referans:

+0

bir de her zaman çalışır basit neden daha karmaşık bir imza için tercih "Ama burada 4 imza kullanmalıdır"? – newacct

+0

@newacct. Diğer alternatiflerin açık tip argümanlarla çalışmadığını zaten açıklamıştım. Ve bu yöntemin açık tip argümanı olan veya olmayan çağrılacak olup olmadığını bilmiyorsunuz. –

+0

* Doğru * açık tür bağımsız değişkeniniz varsa, açık tür bağımsız değişkenlerle çalışır. Bu imza ve bağımsız değişkenler için yanlış olan bir tür bağımsız değişken seçerseniz, bu imzanın sorunu değildir. – newacct

İlgili konular