2015-05-18 13 views
6

Mi piacerebbe sapere l'uso di? nei generici di java. Studiando il segnaposto T e il jolly? , Mi chiedevo?, Passò attraverso diversi siti/pagine e libri ma non riuscì a capirlo. Così ho creato la classe di sotto per studiare le differenze.Che cosa si intende per avere? in 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 

    } 

} 

Qui, in un caso, ci potrebbero essere diversi scenari mancanti dalla mia classe in modo da ciò che ho scritto è incompleto, in questo caso, chiunque può aiutarmi a capire più scenari. O ho trovato? come ridondante, eccetto che fornisce caratteristiche come l'uso di parole chiave super e caratteri minori nella firma di un metodo insieme al tipo di ritorno.

MODIFICA: Fondamentalmente la mia domanda è conoscere le ragioni che stanno dietro, lo scopo dell'introduzione? carattere jolly in cui un tipo generico può sostituirlo ovunque. Non è la domanda su come usare? o tipi T. Ovviamente, conoscendo il suo utilizzo fornirai dei parenti. Ad esempio, le cose che ho dedotto:

  • ? rende il codice più leggibile e meno facile da codificare in determinati posti
  • A volte riduce il gonfiore del codice.
  • Possiamo usare le super classi, cosa non possibile con il tipo T.
  • Limita l'aggiunta di nuovi elementi casuali a un elenco. Dove il casting (senza classcastexception) è valido per il tipo T a volte.

C'è dell'altro?

+0

richiesta di amministratore o moderatore. Ci vorrà un momento o un giorno o due per passare attraverso questi per capire. Quindi, per favore, lasciami passare attraverso ogni link fornito per questa domanda. – smslce

+0

Non so come funzioni la cancellazione di domande duplicate ma non mi aspetterei che accada presto, se non del tutto. – biziclop

risposta

2

Si utilizzano i caratteri jolly illimitati quando l'elenco (o la raccolta) è di tipi sconosciuti.

si dovrebbe mai usare quando si vuole per esempio per inserire valori a un elenco (dal momento che l'unico valore è possibile inserire è null).

E 'usato quando si vuole ottenere informazioni su alcuni struttura dei dati, come la stampa il suo contenuto, quando si non si sa che tipo si potrebbe contenente. Ad esempio:

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

Non è la stessa come in seguito. <- la lingua: lang-java -> public static StampaLista vuoto (Lista lista) { \t \t per (elem Oggetto: lista) \t sistema. out.print (elem + ""); \t System.out.println(); \t} – smslce

3

? significa: il tipo è specificato. Significato: se non c'è altra ragione nel tuo codice che richiede che tu abbia un parametro di tipo "named"; puoi/dovrebbe usare ? per esprimere esattamente questo.

E in realtà, ho chiesto che qualche tempo fa, per cui si potrebbe trovare le risposte qui utili: Java generics: wildcard<?> vs type parameter<E>?

+0

Ho letto il collegamento fornito, quando guardo la risposta che hai selezionato è iniziato dicendo che a volte non c'è differenza tra? e T . Più tardi spiega che il placeholder generico è più utilizzabile di? carattere jolly (riferendosi all'errore dovuto a?) che ritorna alla domanda sull'uso di?. Puoi anche dare più informazioni sull'affermazione "se non c'è altro motivo nel tuo codice che richiede che tu abbia un parametro di tipo" named "". Significa che nessun parametro di tipo viene utilizzato nell'intera classe in cui è implementato o solo nel metodo in cui è necessario passare qualcosa. – smslce

+0

Il punto è: se hai bisogno di scrivere "T"; allora dovresti usare "T". Se il tipo è sconosciuto e di nessuna importanza, che scrivere "?" lo rende più esplicito (ma potresti comunque usare "T" invece di "?") – GhostCat

+0

puoi aggiungere qualcosa alla mia lista nella domanda modificata. – smslce

1

Qualcuno ha scritto una buona risposta a questa domanda here. Il punto interrogativo significa fondamentalmente "qualsiasi tipo", ma può essere molto utile quando si lavora con interfacce o classi astratte. Ad esempio,

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

Questo è utile perché è ancora ottenere il controllo di tipo, per assicurarsi che qualsiasi cosa mettere nella vostra lista è una sottoclasse di MyClass. Se avessi un particolare metodo o campo nella classe astratta con cui dovevi lavorare, puoi lavorare con esso per tutte le sottoclassi indipendentemente dall'implementazione specifica.Per un esempio più reale, lo uso per il routing degli 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); 
    }}; 
Problemi correlati