2012-02-29 14 views
13

De alguna manera mi vieja pregunta se cerró, por lo que abrir una nueva:¿Cómo evitar las advertencias elenco sin marcar con Java Generics

estoy usando genéricos de Java para implementar un genérico Hash bidireccional Mapa de una consulta SQL. Debería poder mapear cualquier combinación de String, Integer pares de ida y vuelta. Se debe utilizar la siguiente manera:

String sql = "SELECT string_val, int_val FROM map_table"; 
PickMap<String, Integer> pm1 = new PickMap<String, Integer>(sql); 

String key1 = "seven"; 
Integer value1 = pm1.getLeft2Right(key1); 

Integer key2 = 7; 
String value2 = pm1.getRightToLeft(key2); 

Por supuesto que debería ser posible crear un pm (entero, entero) y así sucesivamente ...

Mi implementación de recogida Mapa ve así (sin el getter ...):

public class PickMap<L, R> { 

    private final HashMap<L, R> left2Right = new HashMap<L, R>(); 
    private final HashMap<R, L> right2Left = new HashMap<R, L>(); 

    public PickMap(String sql) throws OException { 
     DTable d = new DTable(sql); 
     int colTypeL = d.t.getColType(1); 
     int colTypeR = d.t.getColType(2); 
     Extractor<L> extLeft = (Extractor<L>) getInstance(colTypeL); 
     Extractor<R> extRight = (Extractor<R>) getInstance(colTypeR);  
     int numRows = d.t.getNumRows(); 
     for(int i=1;i<=numRows;i++) { 
      L leftVal = extLeft.extract(d, i); 
      R rightVal = extRight.extract(d, i); 
      this.left2Right.put(leftVal, rightVal); 
      this.right2Left.put(rightVal, leftVal); 
     } 
    } 

    private Extractor<?> getInstance(int type) { 
     if(type == 1) 
      return new IntExtractor(); 
     else 
      return new StringExtractor(); 
    } 
} 

interface Extractor<E> { 
    E extract(DTable source, int row); 
} 

class IntExtractor implements Extractor<Integer> { 

    @Override 
    public Integer extract(DTable source, int row) { 
     int value = 5; 
     return new Integer(value); 
    } 
} 

class StringExtractor implements Extractor<String> { 

    @Override 
    public String extract(DTable source, int row) { 
     String retVal = "hello"; 
     return retVal; 
    } 
} 

que no tienen errores de compilación y estoy bastante seguro, que va a trabajar de esta manera. PERO estoy obteniendo advertencias de lanzamiento sin marcar en los métodos "getInstance" Donde echo el Extractor (E) al Extractor (L) ...

¿Cómo debo lanzar correctamente? ¿O qué me estoy perdiendo? ¿O debería simplemente suprimir esas advertencias?

Respuesta

24

Recibes advertencias porque no se puede probar que lo que estás haciendo sea seguro. Usted es suponiendo que getInstance(colTypeL) devolverá Extractor<L> - pero eso no se puede verificar ni en tiempo de compilación ni en tiempo de ejecución.

Puede usar @SuppressWarnings("unchecked") como lo mencionaron otros, pero trataría de repensar el diseño un tanto.

+0

Sí, entiendo su punto. Me gustaría utilizar el tipo genérico L para la instanciación de mi Extractor. Entonces, en lugar de dar el "colType" en el método getInstance, me gustaría hacer algo como getInstance (L) y getInstance (R) ... ¿Es posible? ¡Odio suprimir advertencias! – Sauer

+1

@Sauer: Debería conocer 'L' y' R' en tiempo de ejecución, lo que normalmente significa tener parámetros de constructor de tipo 'Clase ' y 'Clase ' o algo similar. –

+8

Una posibilidad es hacer que el constructor tome los extractores que necesita: 'PickMap (String sql, Extractor leftExtractor, Extractor rightExtractor>)'. Esto no solo hace que la compilación sea segura, sino que también permite que otra persona comparta y decida que quiere un 'PickMap ' sin tener que cambiar el código 'PickMap' (suponiendo que' Extractor' es una interfaz o clase a la que tienen acceso a). – yshavit

5

Usted puede utilizar la siguiente anotación para que el compilador no se emiten las advertencias:

@SuppressWarnings("unchecked") 

ver este related question que se ocupa de la misma cuestión. La respuesta allí explicará todo lo que necesita saber.

Cuestiones relacionadas