2016-07-19 31 views
11

Genel ve dökümeyi anlıyorum ancak genel döküm işlemini anlamıyorum. Ben sadece belirli tip yukarı veya aşağı kalıtım ağacın içinden yayınlayabileceğim düşündüm ama bu bana yanlış oldu: Bu en iyi örnek olmayabilir ama umarım benim noktası olacaktırGenel değişkene dökümü

ArrayList<?> cislo = (ArrayList<? extends Number>) new ArrayList<Integer>(); 

. Bu nasıl çalışıyor? Ne tür bir türeve giriyor?

+1

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

+0

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

+0

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 clazz = null; halinde (Bool.FALSE.equals (Property.ENABLED.get (konfigürasyon))) { clazz = DummyStorage.class; } else { clazz = (Sınıf genişletir) Property.STORAGE.get (configuration); } (clazz.isAssignableFrom (DummyStorage.class)) {yeni DummyStorage geri halinde(); }} '' –

cevap

4

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:

  • ? T < =? genişletir T <: S

  • ? T < =? genişletir Bu tanımda ArrayList<? extends Number> tarafından

[...] 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

+0

ise dökme gerekli olan "döküm gereksizdir." - dediğim gibi en iyi örnek olamazdı. Bunu okumak gerçekten çok zor, ama açıklaman gerçekten yardımcı oldu, teşekkürler. Ek bilgiler burada http://stackoverflow.com/questions/2776975/how-can-i-add-to-list-extends-number-data-structures bulunabilir –