2015-05-18 23 views
6

Chciałbym poznać wykorzystanie? w generycznych elementach java. Badając symbol zastępczy T i znak wieloznaczny? , Zastanawiałem się ?, przeszedł przez kilka stron/stron i książek, ale nie udało się go zrozumieć. Stworzyłem więc poniższą klasę, aby zbadać różnice.Jaki jest pożytek z posiadania? w java

import java.util.List; 

public class Generics2 { 

    public <T> void method1(List<T> list){ 
     System.out.println(list); 
    } 

    public <T extends Number> void method2(List<T> list){ 
     System.out.println(list); 
    } 

    /*public <T super Integer> void method3(List<T> list){ 

    }*///super does not work. 

    public void method4(List<?> list){ 
     System.out.println(list); 
    } 

    public void method5(List<? extends Number> list){ 
     System.out.println(list); 
    } 

    public void method6(List<? super Integer> list){ 
     System.out.println(list); 
    } 

    public <T> void copy1(List<T> list1, List<T> list2){ 
     //copy elements from list1 to list2 

    }//It does not span well with copy of one type of elements from list1 to other type elements in list2, where the list elements 
    //between the two are not same but are related through inheritance. 

    public <T1,T2> void copy2(List<T1> list1,List<T2> list2){ 
     //copy elements from list1 to list2, right now we do not bother about the exceptions or errors that might generate. 
    }//Our intention here is not to copy elements with relation between T1 and T2. We intend to explore the differences on T and ? 

    public void copy3(List<?> list1,List<?> list2){ 
     //copy elements from list1 to list2, right now we do not bother about the exceptions or errors that might generate. 
    }//Our intention here is not to copy elements with relation between T1 and T2. We intend to explore the differences on T 

    public <T1 extends Object, T2 extends Object> void copy4(List<T1> list1, List<T2> list2){ 
     //copy elements from list1 to list2 
    } 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 

    } 

} 

Tutaj, w jednym przypadku, nie może być kilka scenariuszy brakujące z mojej klasy, więc to, co napisałem jest niepełna, w tym przypadku może ktoś mi pomóc zrealizować kolejne scenariusze. Albo znalazłem? jako nadmiarowe z, z wyjątkiem takich funkcji, jak użycie super-słowa kluczowego i znaków mniejszych w metodzie podpisu wraz z typem zwracanym.

EDYTOWANIE: Zasadniczo moim pytaniem jest poznać przyczyny, cel wprowadzenia? wildcard, gdzie typ ogólny może go zastąpić wszędzie. Nie chodzi o to, jak używać? lub typy T. Oczywiście, znając jego użycie, zapewni pewne sposoby. Na przykład, rzeczy, które wydedukowałem:

  • ? czyni kod bardziej czytelnym i mniej łatwym do kodowania w pewnych miejscach miejsc
  • Redukuje czasem wzdęcia kodu.
  • Możemy użyć superklas, co nie jest możliwe w przypadku typu T.
  • Ogranicza dodawanie nowych losowych elementów do listy. Gdzie casting (bez wyjątku klasycast) jest czasem ważny dla typu T.

Czy są jeszcze jakieś?

+0

wniosek do administratora lub moderatora. Trwa to przez jakiś dzień lub dwa, aby je zrozumieć. Proszę, pozwól mi przejść przez każdy link podany dla tego pytania. – smslce

+0

Nie wiem, jak działa usuwanie duplikatów pytań, ale nie spodziewam się, że nastąpi to wkrótce, jeśli w ogóle. – biziclop

Odpowiedz

2

Używasz nieograniczonych symboli wieloznacznych, gdy lista (lub kolekcja) jest z nieznanych typów.

Nigdy nie należy go używać, gdy chcesz na przykład wstawić wartości do listy (ponieważ jedyną wartością, którą można wstawić, jest null).

Jest używany, gdy chcemy dostać informacje o niektórych struktury danych, jak drukowanie jej zawartość, po nie wiem jakiego rodzaju może być zawierające. Na przykład:

public static void printList(List<?> list) { 
    for (Object elem: list) 
     System.out.print(elem + " "); 
    System.out.println(); 
} 
+0

nie jest to samo, jak następuje. <- język: język-java -> public static void rozszerza Object List printList (lista) { \t \t dla (Object elem: lista) \t System. out.print (elem + ""); \t System.out.println(); \t} } – smslce

3

? oznacza: typ jest nieokreślony. Znaczenie: jeśli nie ma innej przyczyny w kodzie, która wymaga, że ​​masz "nazwany" parametr; możesz/powinien używać ?, aby wyrazić dokładnie to.

I rzeczywiście, poprosiłem, że jakiś czas z powrotem, więc można znaleźć odpowiedzi tutaj pomocne: Java generics: wildcard<?> vs type parameter<E>?

+0

Przeczytałem podany link, Kiedy patrzę na wybraną odpowiedź, zaczyna się od stwierdzenia, że ​​nie ma różnicy między? oraz T . Później wyjaśniono, że rodzajowy symbol zastępczy jest bardziej użyteczny niż? wildcard (odnosząc się do błędu z powodu?), który powraca do pytania na temat użycia?. Możesz również podać więcej informacji na temat stwierdzenia "jeśli nie ma innego powodu w kodzie, który wymaga, że ​​masz" nazwany "parametr typu". Czy oznacza to brak parametru typu używanego w całej klasie, w której jest on implementowany, czy tylko w metodzie, w której musimy coś przekazać. – smslce

+0

Chodzi o to, że jeśli potrzebujesz napisać "T"; wtedy powinieneś użyć "T". Jeśli typ jest nieznany i bez znaczenia, niż pisanie "?" czyni to bardziej wyraźnym (ale nadal możesz użyć "T" zamiast "?") – GhostCat

+0

możesz dodać coś do mojej listy w edytowanym pytaniu. – smslce

1

Ktoś napisał nawet dobrą odpowiedź na to pytanie here. Znak zapytania w zasadzie oznacza "dowolny typ", ale może być bardzo przydatny podczas pracy z interfejsami lub klasami abstrakcyjnymi. Na przykład,

List<? extends MyAbstract> myClasses = new ArrayList<? extends MyAbstract>(); 

Jest to przydatne, ponieważ wciąż typ kontroli, aby upewnić się, że cokolwiek umieścić na liście jest podklasą MojaKlasa. Jeśli dysponujesz określoną metodą lub polem w klasie abstrakcyjnej, z którą musisz pracować, możesz z nią pracować dla wszystkich podklas, niezależnie od konkretnej implementacji.Aby uzyskać bardziej rzeczywisty przykład, używam tego do routingu adresów URL:

Map<String, Class<? extends IJSONService>> routes = new HashMap<String, Class<? extends IJSONService>>(){ 
    { 
    put("default", EmployeeFinderSearch.class); 
    put("", EmployeeFinderSearch.class); 
    put("reports", EmployeeFinderReports.class); 
    put("me", Me.class); 
    put("email", SendEmail.class); 
    put("image", UploadImage.class); 
    put("excel", ExportExcel.class); 
    }}; 
Powiązane problemy