2010-10-01 7 views
6

Ho il seguente codice di prova:Non può compilare una classe che implementa un'interfaccia senza tipo di parametro

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

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

ed ottengo il seguente errore quando si tenta di compilare questi due classi:

myContainer. java: 1: MyContainer non è astratto e non sovrascrive il metodo astratto addClass (java.lang.Class) nel contenitore

Se aggiungo un tipo all'interfaccia Container e in MyContainer (come <Object>), non ho ricevuto l'errore.

Il problema è che sto introducendo il parametro type su Container, che fa parte dell'API pubblica, quindi per compatibilità, non posso avere tutte le classi di implementazione impossibili da compilare.

Qualcuno ha qualche idea? È un problema di cancellazione del tipo? C'è una soluzione?

risposta

7

Penso che il problema è che se si usano i tipi non elaborati ovunque nella dichiarazione della classe, si sta optando per i generici. Quindi funzionerà - nota il cambiamento dei parametri.

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

Da section 4.8 of the JLS:

Le superclassi (rispettivamente, superinterfacce) di un tipo grezzo sono i cancellature delle superclassi (superinterfacce) di una qualsiasi delle sue invocazioni parametri.

Io credo che la parte più importante ... la cancellazione dei Container<T>.addClass(Class<?> clazz) è addClass(Class clazz).

Ma sì, in pratica, a meno che non si tratti di codice legacy autentico, si dovrebbe considerare l'introduzione di un parametro di tipo in un'interfaccia come una modifica di rottura.

+0

@ elaborazione Skeet- sarebbe helpful..TIA – hakish

+0

Vedo, grazie Jon. Accettato. –

3

Come liberarsi se le <?> lo fissa:

public void addClass(Class clazz) {} 

Il messaggio di errore non è molto descrittivo:

Nome scontro: Il metodo addClass (Class) di tipo myContainer ha lo stesso cancellazione di addClass (Class) di tipo Container ma non lo sovrascrive

Ciò significa che entrambi i metodi sono uguali quando i tipi di eir vengono cancellati, ma il metodo di sottoclasse non implementa/sovrascrive quello della superclasse/interfaccia.Questo non ha molto senso, e presumo che sia perché hai scelto di non usare i generici nella sottoclasse, devi attenersi a quello (e non perameterizzare Class)

3

Se la tua classe usa Generics allora una soluzione semplice sarebbe quello di fare questo:

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

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

Oppure, se si conosce già il tipo di contenitore che hai,

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

Se la classe non usa Generics (pre 1.5), allora non si può avere la parte <?>. Quindi non ci saranno problemi reali qui.

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

Implementare l'interfaccia dovrebbe funzionare (come per tipo di cancellazione) come segue:

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