È possibile evitare gli avvisi non controllati quando si esegue l'override di un metodo con parametri di tipo non elaborati?

StackOverflow https://stackoverflow.com/questions/241539

Domanda

Sto estendendo una classe definita in una libreria che non posso cambiare:

public class Parent
{
    public void init(Map properties) { ... }
}

Se sto definendo una classe 'Child' che estende Parent e sto usando Java 6 con generics, qual è il modo migliore per sovrascrivere il metodo init senza ricevere avvisi non controllati?

public class Child extends Parent
{
    // warning: Map is a raw type. References to generic type Map<K,V> should be parameterized
    public void init(Map properties) { }
}

Se aggiungo parametri generici, ottengo:

   // error: The method init(Map<Object,Object>) of type Child has the same erasure as init(Map) of type Parent but does not override it
   public void init(Map<Object,Object>) { ... }
   // same error
   public void init(Map<? extends Object,? extends Object>) { ... }
   // same error
   public void init(Map<?,?>) { ... }

Questo errore si verifica indipendentemente dal fatto che io utilizzi un tipo specifico, un carattere jolly associato o un carattere jolly non associato. Esiste un modo corretto o idiomatico per sovrascrivere un metodo non generico senza avvisi e senza utilizzare @SuppressWarnings (& Quot; non spuntato & Quot;)?

È stato utile?

Soluzione

Sì, devi dichiarare il metodo di sostituzione con la stessa firma della classe genitore, senza aggiungere alcuna informazione generica.

Penso che la tua scommessa migliore sia quella di aggiungere l'annotazione @SuppressWarnings("unchecked") al parametro raw-type, non il metodo, quindi non eliminerai gli altri avvisi generici che potresti avere nel tuo codice.

Altri suggerimenti

Risposta breve: nessun modo per farlo.

Risposta insoddisfacente: disabilita gli avvisi (specifici) nel tuo IDE / build.xml.

Se non è possibile modificare la libreria, purtroppo, è necessario attenersi a metodi non generici.

Il problema è che, nonostante dopo la cancellazione del tipo, entrambi init () abbiano la stessa firma, possono in effetti essere metodi diversi o uguali (*). Il compilatore non può dire se deve eseguire l'override o il sovraccarico, quindi è proibito.

(*) Supponiamo che lo sviluppatore della libreria intendesse init (Mappa & Lt; String, Integer & Gt;). Ora stai implementando init (Map & Lt; String, String & Gt;). Questo è un sovraccarico e due metodi dovrebbero esistere nella vtable della classe Child.

Ma cosa succederebbe se lo sviluppatore della libreria intendesse init (Map < String, String >)? Quindi ha la precedenza e il tuo metodo dovrebbe sostituire init originale nella classe Child e ci sarebbe un solo metodo nella tabella di Child.

P.S. Odio il modo in cui Generics ha implementato in Java :-(

Penso che la risposta sopra abbia significato invece dire @SuppressWarnings (" rawtypes ").

Devi dichiarare il metodo con la stessa firma del genitore, e quindi riceverai degli avvisi durante la compilazione. Puoi eliminarli con @SuppressWarnings (& Quot; non selezionato & Quot;)

Il motivo per cui non c'è modo di sbarazzarsi di questo è che gli avvisi sono lì per farti sapere che è possibile creare raccolte con tipi non validi al loro interno. Gli avvisi dovrebbero sparire solo quando tutto il codice che potrebbe consentire che sia stato rimosso. Poiché stai ereditando da una classe non generica, sarà sempre possibile creare una raccolta con contenuti non validi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top