2013-01-09 9 views
19

Czytałem o rodzajach ogólnych i nie rozumiałem potrzeby stosowania niezwiązanych symboli wieloznacznych i tego, jak różnią się one od typu nieprzetworzonego. Czytałem this question, ale nadal nie zrozumiałem tego wyraźnie. W Java tutorial page for unbound wildcard mam poniżej dwóch punktów, a ja nie rozumieć pierwszy punkt:Różnica między niezwiązanym symbolem wieloznacznym a typem nieprzetworzonym

  • Jeśli piszesz metody, które mogą być realizowane z wykorzystaniem funkcjonalności dostarczanej w klasie Object.
  • Gdy kod używa metod w klasie ogólnej, które nie zależą od parametru typu. Na przykład: List.size() lub List.clear(). W rzeczywistości tak często używa się Class<?>, ponieważ większość metod w Class<T> nie zależy od T.

Czy ktoś mógłby wyjaśnić różnicę między niezwiązanym symbolem wieloznacznym a typem surowym w języku laika.

Czym różni się List<?> od List<Object>?

+1

Należy zauważyć, że termin "surowy typ" odnosi się do nieparametrycznego odniesienia do rodzaju ogólnego, np. 'List' vs.' Lista '. Nieco różne koncepcje. – Alex

+4

Tylko zwrócić uwagę, że 'List ' nie jest typem surowym, jego typem ogólnym jest 'Obiekt'. Typ surowy to "Lista". – Dmitri

Odpowiedz

33

Jak List<?> różni się od List<Object>

Główną różnicą jest to, że pierwsza linia kompiluje ale drugi nie:

List<?> list = new ArrayList<String>(); 
List<Object> list = new ArrayList<String>(); 

Jednakże, ponieważ nie wiem, co rodzajowe typ List<?> to, że nie można użyć sparametryzowanych metod:

List<?> list = new ArrayList<String>(); 
list.add("aString"); //does not compile - we don't know it is a List<String> 
list.clear(); //this is fine, does not depend on the generic parameter type 

chodzi o różnicę z surowych typów (bez leków generycznych), poniższy kod kompiluje i działa poprawnie:

List list = new ArrayList<String>(); 
list.add("aString"); 
list.add(10); 
+0

do tej pory, ale jak surowy jest inny dla niezwiązanych i dlaczego potrzebujemy unboud wildcard? czy możesz wyjaśnić to dobrym przykładem. –

+0

@Sandy główna różnica IMO polega na tym, że użycie niezwiązanego symbolu wieloznacznego (np. W sygnaturze metody) sygnalizuje obietnicę, że dana metoda jest świadoma rodzaju generycznego i będzie honorować ogólny typ tego obiektu. W przypadku typów surowych wszystkie zakłady są wyłączone - możesz dodać liczbę do listy ciągów, tak jak to pokazano tutaj - a mieszanie kodu generycznego i nieprzetworzonego może prowadzić do ryzyka błędów ClassCastExceptions. – Alex

+0

@Sandy Zilustrowałem różnicę między typami bezopisowymi (drugi przykład) i nieprzetworzonymi (przykład 2-ty). Co nie jest dla nich jasne? – assylias

4

Jak List<?> różni się od List<Object>?

List<Object> l1 = new ArrayList(); 
    List<?> l2 = new ArrayList(); 
    l1.add("Object"); 
    //l2.add("Object"); incorrect 
    l2.add(null); 

Można dodać tylko zerową wartość do List<?>

2

Osobiście uważam, że ten additional link from the Java tutorial on wildcards pomocne.

Jedną z głównych różnic widzę między List<?> i List jest to, że ten pierwszy może być tylko przydatne do czytania od jego elementów (chyba że naprawdę chcesz dodać null), ten ostatni pozwala (niezaznaczone) dodanie dowolnie wpisywanych obiektów z możliwymi nieoczekiwanymi efektami ubocznymi.

0

Lista jest przydatna w sygnaturze metody do wywoływania metod, które nigdy nie wymagają parametru typu, np. Odczytu z listy lub obrócenia go, na przykład.

void someMethod(List<?> list) { 
    list.clear(); // I will never add anything to the list in here 
} 

Ty nigdy niczego lub w inny sposób zmodyfikować listę w odniesieniu do typu to trzyma jak nie możesz dodać coś do listy wyjątkiem zerowy w metodach z tego podpisu, a tym samym nie będzie kiedykolwiek przerwać typu bezpieczeństwa. Surowa lista z drugiej strony możesz zrobić wszystko, co, jak wszyscy wiemy, może spowodować naruszenie bezpieczeństwa typu.

void someMethod2(List list) { 
list.add(new WeaselFurBrush()); 
} 
List list1 = new ArrayList<String>(); 
someMethod2(list1);// oops 
Powiązane problemy