2013-08-11 23 views
6

Sono abbastanza sicuro che questo è sicuro, ma volevo solo verificare come Eclipse mi stia chiedendo di inserire un'annotazione @SuppressWarnings("unchecked").Il mio tipo di codice è sicuro?

Map<String, IFace> faces; 

public <T extends IFace> T getFace(String key) 
{ 
    return (T) faces.get(key); 
} 
+5

Rispondere alla mia domanda: No, non è perché posso avere due DIFFERENT classi 'ClassA' e' ClassB' che implementano entrambi 'IFace' in' faces'. A runtime 'T' potrebbe essere' ClassA' o 'ClassB'. – Cheetah

+0

Speciali come sono molto interessato a un problema simile –

+2

Perché i generici sono qui? Se stai solo riferendo le cose come 'IFace', allora non hai bisogno dei generici/casting –

risposta

4

Non è sicuro. Stai trasmettendo qui in modo che se passi a una classe derivata incompatibile ti imbatterai in un errore ad un certo punto.

Ad esempio se A_Face e B_Face entrambi estendono IFace. A un certo punto potresti lanciare un B_Face come A_Face che non è sicuro da testo.

0

Guarda il caso estremo. Diciamo IFace è acutally Object, il codice sia poi così:

static Map<String, Object> myMap = new HashMap<>(); 

public static void main(String[] args) throws Exception { 
    myMap.put("ONE", 1); 
    myMap.put("TWO", "TWO"); 
    myMap.put("THREE", new Date()); 

    final Calendar calendar1 = getThing("ONE"); 
    final Calendar calendar2 = getThing("TWO"); 
    final Calendar calendar3 = getThing("THREE"); 
} 

public static <T> T getThing(String key) { 
    return (T) myMap.get(key); 
} 

Così si stanno mettendo a class di extends Object nella vostra Map (in modo che qualsiasi class).

Tuttavia, quando si chiama getThing si esegue una trasmissione implicita sul tipo desiderato. Dovrebbe essere abbastanza ovvio che posso chiamare lo getThing con qualsiasi class e tenterò ciecamente di lanciarci su di esso.

Nell'esempio precedente sto inserendo alcune cose nel mio Map e quindi nel tentativo di recuperarle tutte come Calendar s.

0

Un modo classico per gestire questa situazione è un "contenitore eterogeneo typesafe":

Map<Class<?>, IFace> faces; 

public <T extends IFace> T getFace(Class<T> key) { 
    return t.cast(faces.get(key)); 
} 

si utilizza la classe dell'interfaccia come una chiave, piuttosto che una stringa, e quindi è possibile utilizzare la classe passata come chiave per trasmettere in modo sicuro il valore restituito al tipo corretto.