Generisches Methode Typ Sicherheit
Frage
Ich habe das Konzept der NodeType
s und Node
s. Ein NodeType
ist ein Bündel von Meta-Daten, die Sie Node
Instanzen aus (viel wie die ganzen Klasse / Objekt-Beziehung) erstellen können.
Ich habe verschiedene NodeType
Implementierungen und verschiedene Knoten-Implementierungen.
In meinem AbstractNodeType (Top-Level für NodeTypes) Ich habe ab abstrakt createInstance()
Methode, wird, sobald sie von der Unterklasse implementiert, schafft die richtige Knoten Beispiel:
public abstract class AbstractNodeType {
// ..
public abstract <T extends AbstractNode> T createInstance();
}
In meinem NodeType
Implementierungen implementieren ich die Methode wie folgt aus:
public class ThingType {
// ..
public Thing createInstance() {
return new Thing(/* .. */);
}
}
// FYI
public class Thing extends AbstractNode { /* .. */ }
Das ist alles schön und gut, aber public Thing createInstance()
schafft eine Warnung über die Typsicherheit. Im Einzelnen:
Typ Sicherheit: Der Rückgabetyp Sache für createInstance () von dem Typ ThingType muss nicht markiert Umwandlung T vom Typ übereinstimmen AbstractNodeType
Was mache ich falsch, eine solche Warnung verursachen?
Wie kann ich wieder Faktor meinen Code dieses Problem beheben?
@SuppressWarnings("unchecked")
ist nicht gut, ich wünsche, dieses Problem zu beheben, indem sie es richtig Codierung, nicht ignoriert das Problem!
Lösung
Sie können nur <T extends AbstractNode> T
mit AbstractNode
dank der Magie ersetzen covariant kehrt . Java 5
zusätzliche Unterstützung, aber sie wurde nicht in die Kneipe es verdient.
Andere Tipps
Zwei Möglichkeiten:
(a) Sie keine Generika verwenden. Es ist wahrscheinlich in diesem Fall nicht erforderlich. (Obwohl das hängt von dem Code, den Sie gezeigt havn't.)
(b) Generify AbstractNodeType wie folgt:
public abstract class AbstractNodeType<T extends AbstractNode> {
public abstract T createInstance();
}
public class ThingType<Thing> {
public Thing createInstance() {
return new Thing(...);
}
}
So etwas sollte funktionieren:
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();
}
}