Oyuncular gereksizdir.
atamaları
ArrayList<?> list = new ArrayList<Integer>();
ArrayList<? extends Number> list2 = new ArrayList<Integer>();
herhangi açık dökümü gerektirmez.
Joker tür beton türlerinden daha/"daha az spesifik" türleri "genel", ve upper bounded wildcard types (gibi ? extends Number
) unbounded ones (?
) daha özeldir.
Joker türleri arasındaki ilişki hakkında daha fazla bilgi Oracle Tutorial on Wildcards and Subtyping adresinde bulunabilir.
JLS bu belirtme ilgili kısmı genel tür bildirimi C (n> 0) Verilen 4.10.2. Subtyping among Class and Interface Types
olduğunu Ti (1 ≤ i n ≤) parametreli tip C, doğrudan supertypes D genel tip C ve θ'nın doğrudan süper tıp bir genel türü
- D, ikame [F1 edilir: = T1, ..., Fn türüdür aşağıdakilerden tümü : = Tn]. Si'nin Ti (1 ≤ i ≤ n) (§4.5.1) içerdiği yerlerde C,
- C.
[...] grubu ise, bir tür bağımsız değişkeni T1 başka tür bağımsız değişken T2 içeren söylenen 4.5.1. Type Arguments of Parameterized Types
yazılı T2 < = T1 belirtir
T2 ile gösterilen tiplerin, aşağıdaki kuralların (ve <: alt türlemeyi (§4.10) belirtmektedir) altında T1 ile gösterilen tip kümesinin prodüktif bir alt kümesi vardır:
[...] Yani
ArrayList<Integer>
ve ArrayList<?>
bir üst tip olan ham türü dışında herhangi ArrayList<>
bir üst tip olduğunu.
Bir üst tür olan bir değişkene atama, döküm gerektirmez.Bu döküm sonra
Object list = new ArrayList<Integer>();
//...somewhere else - the compiler does not know that list is always an ArrayList, but we tell it that we know what we are doing
List<? extends Number> numbers = (List<? extends Number>) list; //unchecked cast warning, but works
sen mesela can,: Farklı bir tip bir şey atamak istiyorsanız
bir döküm gereklidir listeden öğeler alın ve Number
s olarak davranın. Eğer
java.lang.ClassCastException: java.util.HashSet cannot be cast to java.util.List
sorunlar ortaya başlar atma List<? extends Number>
Object list = new HashSet<Integer>();
List<? extends Number> numbers = (List<? extends Number>) list; //unchecked cast warning
bir alt tür değil list
referansa başka bir şey zamanında başarısız atarsanız dökme zamanında başarısız olur genel tür eşleşmediğinde:
List<String> stringList = new ArrayList<String>();
stringList.add("hi");
Object list = stringList;
List<? extends Number> numbers = (List<? extends Number>) list; //unchecked cast warning, but (sadly) works
Number n = numbers.get(0); //fails: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
Bunun nedeni, çalışma zamanında, liste türlerinin Silme işlemlerinin eşleşmesidir. jenerik bilgileri (tip silinti) kaybolur diye dökme, hiç yoktur Çalışma zamanında da the tutorial on erasure
bakınız. Derleme zamanında derleyiciye 'ArrayList 'dizisini' ArrayList 'olarak işlemesini söyler misiniz? Number> 'öğesini genişletir ve bu konuda sessiz olun (uyarı hariç, temelde" Number "değişkenini" Tamsayı "a çevirdiğinizle aynıdır - derleyiciye ne yaptığınızı bildiğinizi söylersiniz). ArrayList > 'a verilen her durumda çalışır. –
Thomas
Generics ile, döküm kesinlikle gerekli olmamalıdır. Eğer bir Jenerik türünü yazmak istiyorsanız, belki de sadece Generics'in sahip olduğu büyük esnekliği kullanarak "temiz" bir çözüm bulunmadığını kontrol etmelisiniz. Belli bir örneğiniz varsa, pek çok insanın yardım etmeye hazır olduğundan eminim. – martinhh
Belirli bir örneğim var. Ben '@ReesmoConfiguration (saklama = RestApiStorage.class) örneğin' ve soyut üst sınıf Depolama i fabrika yöntemini 'newInstance (Object yapılandırması) { bulundu sonuçları göndermek istediğiniz depolama seçmek için JUnit test açıklama sağlayan framwork ile çalışmak Sınıf Depolama alanını genişletir> clazz = null; halinde (Bool.FALSE.equals (Property.ENABLED.get (konfigürasyon))) { clazz = DummyStorage.class; } else { clazz = (Sınıf Depolama> genişletir) Property.STORAGE.get (configuration); } (clazz.isAssignableFrom (DummyStorage.class)) {yeni DummyStorage geri halinde(); }} '' –