2012-06-28 11 views
6

Tengo algunos problemas con un método que tiene un parámetro de lista tipeado, heredado de otra clase (tipeada).Método con lista tipada y herencia

Vamos a mantenerlo simple:

public class B<T> { 
    public void test(List<Integer> i) { 
    } 
} 

La clase B tiene una T inútil genérico, y test() quieren una lista de números enteros.

si hago:

public class A extends B { 
    // don't compile 
    @Override 
    public void test(List<Integer> i) { 
    } 
} 

me sale un "El método de ensayo (lista) de tipo A debe anular o poner en práctica un método supertipo" error, eso no debería suceder.

Pero eliminar el tipo de la lista funciona ... aunque no depende de la clase genérica.

public class A extends B { 
    // compile 
    @Override 
    public void test(List i) { 

Y también la definición de los inútiles genérica a continuación para utilizar la lista mecanografiada

public class A extends B<String> { 
    // compile 
    @Override 
    public void test(List<Integer> i) { 

Así que no tengo ni idea, la genérica de B debe tener ninguna influencia sobre el tipo de la lista de pruebas(). ¿Alguien tiene una idea de lo que está pasando?

Gracias

+0

Creo que su respuesta es [aquí] (http://stackoverflow.com/a/502770/248082). – nobeh

+0

Convencionalmente [capital V] 'Void' se usa para los parámetros genéricos que no desea usar. Por ejemplo, que usa 'java.security.PreivilegedAction' sin devolver un valor (devuelve' null' - es la única referencia 'Void' válida). –

Respuesta

8

Está extendiendo el tipo sin procesar de B, no el genérico. La cruda efectivamente no tiene un método test(List<Integer> i), sino un método test(List).

Si cambia a tipos sin procesar, todos los genéricos se reemplazan por cabos, independientemente de si su tipo se completó o no.

para hacerlo correctamente, haga

public class A<T> extends B<T> 

Esto utilizará el tipo genérico B<T>, que incluye el método que desea anular.

+0

Gracias. No es realmente lógico ya que no estamos usando T, pero los genéricos de Java tienen algunos defectos de diseño con los que debemos lidiar. – PomPom

1

Cuando se quita utilizar una clase sin los genéricos (y utilizarlo en bruto), todos los genéricos de métodos de clase se olvidan.

Por este motivo, cuando informa el tipo genérico en el segundo caso, lo pone en funcionamiento.

Este:

class T<G> { 
    public void test(G g); 
} 

en este caso:

class A extends T { 
} 

se verá así:

class T { 
    public void test(Object g); 
} 

Este fue un puzzle java presentado en Google IO 2011 se puede ver el vídeo here

+0

El verdadero problema es que no estaba usando G sino una clase concreta. De todos modos recibí mi respuesta – PomPom

+0

Estabas usando una clase sin procesar. –