2013-02-22 16 views
10

Sto ancora imparando i farmaci generici e ho una domanda. Diciamo che avevi questa classe generica:Qual è la differenza tra queste istruzioni in una classe generica?

public class Test<T> { 

    public static void main (String[] args) { 
     Test t1 = new Test(); 
     Test<String> t2 = new Test<String>(); 
     Test t3 = new Test<String>(); 
    } 
} 

Tutte le dichiarazioni vengono compilate ma non so davvero cosa le rende diverse. Qualcuno può darmi una breve spiegazione su queste tre affermazioni.

+0

quasi vero. Gli altri due solo avvisi pubblicitari, ma non errore di compilazione reale. –

risposta

9
Test t1 = new Test(); 

Qui si utilizza un tipo grezzo. vale a dire, non passando un Type argument per il tuo generic clas s.

compilatore dovrebbe darvi un avvertimento qui

test è un tipo grezzo. I riferimenti al tipo di test generici dovrebbero essere parametrizzato

Test<String> t2 = new Test<String>(); 

qui si utilizza farmaci generici. passando String come type argument al tuo generic class.

Test t3 = new Test<String>(); 

compilatore dovrebbe anche dare un avvertimento anche qui:

  • Test è un tipo grezzo. I riferimenti al tipo di test generici dovrebbero essere parametrizzati

stesso del vostro primo caso, ma si stanno utilizzando tipo parametrico invocando il costruttore.

C'è anche un'altra classe che funziona bene nelle versioni di + java 7.

Test<String> t4 = new Test<>(); 

No compilatore di avvertimento qui se si utilizza + Java 7 a causa di Type Inference

In questo caso a causa della introduzione di type inference tipo generico è dedotto, quindi non c'è bisogno di fornire il generico digitare durante la chiamata del costruttore.

+1

Dovremmo anche aggiungere che la domanda originale ha mancato due combinazioni: 'Test t4 = new Test()', che non verrà compilato perché tenta di assegnare un riferimento di un tipo non elaborato a uno di un tipo generico; e 'Test t5 = new Test <>()', che compila usando il nuovo "operatore diamante" in Java 7. – yshavit

+1

+1 e poiché java 7 è anche possibile scrivere Test t4 = new Test <>(); che è equivalente alla dichiarazione t2 ... – pgras

+1

@yshavit e pgras l'hanno appena aggiunto ragazzi :) – PermGenError

2

Tutti in realtà creano identici oggetti. L'unica differenza sarà il modo in cui vengono trattati sintatticamente nel resto del codice.

t1 e t3 saranno trattati esattamente nello stesso modo perché sono dello stesso tipo - questa sarà trattata come un oggetto con classe Test, niente di più.

t2 verranno trattati in modo più rigoroso in termini di controllo del tipo. Se si presenta qualche opportunità per il compilatore di utilizzare la sua generica qualità <String>, allora tale qualità sarà richiesta anche per la corrispondenza.

3

I generici forniscono controlli di tipo in fase di compilazione.

aiuta aggiungere esempi di ciò che si può/non si può fare con i tuoi articoli (ho cambiato Test-ArrayList per la facilità di esempi):

ArrayList t1 = new ArrayList(); 
    ArrayList<String> t2 = new ArrayList(); 
    ArrayList t3 = new ArrayList<String>(); 

    // First list can have ANYTHING added to it 
    // Compiler won't check because no generics 
    t1.add(new Integer("7")); 
    t1.add("Hello"); 

    // Second list can only have Strings added to it 
    // Compiler will check and throw compile error for anything else 
    t2.add(new Integer("7")); // doesn't compile 
    t2.add("Hello"); 

    // Third list is interesting... 
    // Again, can have ANYTHING added to it 
    // This is because generics (in Java...) are swapped out at COMPILE time 
    // rather than RUNTIME. The compiler can see that the actual type is just 
    // plain ArrayList 
    // If you like, it's similar to doing: 
    // Object o = (String) new Object(); 
    // The net-effect is everything reduced back to Object 
    t3.add(new Integer("7")); // fine 
    t3.add("Hello"); 
Problemi correlati