Generico Tipo Di Metodo Di Sicurezza
Domanda
Ho il concetto di NodeType
s e Node
s.Un NodeType
è un insieme di meta-dati che è possibile creare Node
le istanze (un po ' come tutta la Classe / Oggetto di relazione).
Ho vari NodeType
le implementazioni e le varie implementazioni di Nodo.
Nel mio AbstractNodeType (livello superiore per NodeTypes) ho ab abstract createInstance()
metodo che, una volta attuata dalla sottoclasse, crea il Nodo corretto esempio:
public abstract class AbstractNodeType {
// ..
public abstract <T extends AbstractNode> T createInstance();
}
Nel mio NodeType
implementazioni di implementare il metodo come questo:
public class ThingType {
// ..
public Thing createInstance() {
return new Thing(/* .. */);
}
}
// FYI
public class Thing extends AbstractNode { /* .. */ }
Questo è tutto bene e buono, ma public Thing createInstance()
crea un avviso circa il tipo di sicurezza.In particolare:
Sicurezza del tipo:Il tipo di ritorno Cosa per createInstance() del tipo ThingType bisogno incontrollato di conversione conforme a T dal tipo di AbstractNodeType
Che cosa sto facendo di sbagliato a causa di un messaggio di avviso?
Come posso re-factor il mio codice per risolvere questo problema?
@SuppressWarnings("unchecked")
non è buona, vorrei risolvere questo problema di codifica correttamente, non ignorare il problema!
Soluzione
È possibile sostituire solo <T extends AbstractNode> T
con AbstractNode
grazie alla magia di covariante restituisce. Java 5
aggiunto il supporto, ma non ho ricevuto il pub è meritato.
Altri suggerimenti
In due modi:
(a) non utilizzare farmaci generici.Probabilmente non è necessario in questo caso.(Anche se questo dipende dal codice che hai di non avere mostrato).
(b) Generify AbstractNodeType come segue:
public abstract class AbstractNodeType<T extends AbstractNode> {
public abstract T createInstance();
}
public class ThingType<Thing> {
public Thing createInstance() {
return new Thing(...);
}
}
Qualcosa del genere dovrebbe funzionare:
interface Node{
}
interface NodeType<T extends Node>{
T createInstance();
}
class Thing implements Node{}
class ThingType implements NodeType<Thing>{
public Thing createInstance() {
return new Thing();
}
}
class UberThing extends Thing{}
class UberThingType extends ThingType{
@Override
public UberThing createInstance() {
return new UberThing();
}
}