2015-05-20 20 views
13

ho questo codice:Java Generics: Bounds multipli

public class Test { 

    public static void main(String[] args) { 
     Test t = new Test(); 
     t.callTest(); 
    } 

    public void callTest() { 
     GenericTest gt = new GenericTest<Date>(); // this line don't compile 
     gt.test(new Date()); 
    } 

    class GenericTest<T extends Date & List> { 
     T x; 

     public void test(T y) { 
      System.out.println(x.toString()); 
     } 
    } 
} 

capisco perché new GenericTest<Date>() non si compila, è perché Data non implementa l'interfaccia List, ma se un'istanza di GenericTest gt = new GenericTest() senza generica, l'intero il codice funziona e non capisco perché. Il test del metodo si aspetta dove T extends Date e implementa List, ma funziona con gt.test(new Date()).

risposta

16

Quando si crea un'istanza in questo modo:

GenericTest gt = new GenericTest() 

si utilizza la versione grezza di GenericTest tipo. Ciò significa che il tipo T verrà sostituito con il primo limite (nel tuo caso, Date). Ecco perché il contratto di metodo di GenericTest#test() ha un parametro Date, ma non uno di List.

Si noti che ogni limite, tranne il primo, deve essere un'interfaccia. Solo il primo limite può essere essere una classe. La ragione di ciò è che non è possibile avere tipi, che ereditano da più di una super-classe.

Quindi, dal momento che solo il primo parametro è una classe, non sarà in grado di interruttore il tipo di parametri e la seguente definizione di classe sarà valida:

class GenericTest<T extends List & Date> { } 
+0

I limiti contano davvero quando si utilizzano i tipi non elaborati? – CKing

+1

Sì, sono importanti. Se hai solo il valore "" (ovvero il parametro di tipo senza limiti), la sostituzione sarà 'Oggetto', tuttavia se hai' 'la sostituzione sarà' Numero'. –

+1

Hai ragione. Il primo limite viene applicato. Ho appena provato. +1 – CKing

-2

Se si crea un generico istanza di classe senza parametri generici il compilatore fornisce un avviso e non controlla più l'utilizzo dell'istanza creata. Per quanto riguarda il motivo per cui il codice funziona senza dichiarare il tipo generico - perché in questo caso T è assunto come Object, qualsiasi tipo è buono

+0

Si presume che 'T sia Oggetto'. Credo che questo non sia corretto. Vedi la risposta di @kocko – CKing