2010-10-01 24 views
6

tengo el siguiente código de prueba:no puede compilar una clase que implementa una interfaz sin parámetro de tipo

public interface Container<I> { 
    public void addClass(Class<?> clazz); 
} 

public class MyContainer implements Container { 
    public void addClass(Class<?> clazz) {} 
} 

y me sale el siguiente error al intentar compilar estas dos clases:

MyContainer. java: 1: MyContainer no es abstracto y no anula el método abstracto addClass (java.lang.Class) en el contenedor

Si agrego un tipo a la interfaz del contenedor e en MyContainer (como <Object>), no obtengo el error.

El problema es que estoy introduciendo el parámetro de tipo a Container, que es parte de la API pública, por lo que para compatibilidad, no puedo tener todas las clases de implementación imposibles de compilar.

¿Alguien tiene alguna idea? ¿Es un problema de borrado de tipo? ¿Hay alguna solución?

Respuesta

7

Creo que el problema es que si utiliza tipos crudos en cualquier parte de la declaración de clase, está optando por los genéricos. Entonces esto funcionará - note el cambio de parámetro.

public class MyContainer implements Container { 
    public void addClass(Class clazz) {} 
} 

De section 4.8 of the JLS:

Las superclases (respectivamente, superinterfaces) de un tipo en bruto son los borrones de las superclases (superinterfaces) de cualquiera de sus invocaciones parametrizadas.

Yo creo esa es la parte relevante ... el borrado de Container<T>.addClass(Class<?> clazz) es addClass(Class clazz).

Pero sí, básicamente, a menos que este sea un código heredado genuino, debe considerar la introducción de un parámetro de tipo en una interfaz como un cambio de última hora.

+0

@ elaboración Skeet- sería helpful..TIA – hakish

+0

veo, gracias Jon. Aceptado. –

3

Deshacerse si los <?> lo fija:

public void addClass(Class clazz) {} 

El mensaje de error no es muy descriptivo:

Nombre choque: El método addClass (clase) de tipo MyContainer tiene el mismo borrado como addClass (Class) de tipo Container pero no lo anula

Esto significa que ambos métodos son iguales cuando th Se borran todos los tipos, pero el método de la subclase en realidad no implementa/anula el de la superclase/interfaz.Esto no tiene mucho sentido, y supongo que es porque ha elegido no usar genéricos en su subclase, tiene que apegarse a eso (y no perameterizar Class)

3

Si su clase usa Genéricos, entonces una solución simple sería la de hacer esto:

interface Container<I> { 
    public void addClass(Class<?> clazz); 
} 

class MyContainer<I> implements Container<I> { 
    public void addClass(Class<?> clazz) {} 
} 

O si ya sabe el tipo de recipiente que tiene,

class MyContainer implements Container<ContainerType> { 
    public void addClass(Class<?> clazz) {} 
} 

Si su clase no utiliza genéricos (pre 1.5), entonces no se puede tener la parte <?>. Entonces no habrá ningún problema real aquí.

class MyContainer implements Container { 
    public void addClass(Class clazz) {} 
} 
0

La implementación de la interfaz de la siguiente manera debería funcionar (según el tipo de borrado):

public class MyContainer implements Container { 
    public void addClass(Class clazz) {} 
} 
Cuestiones relacionadas