2008-09-17 13 views
2

Ich habe das Konzept von NodeType s und Node s. A NodeType ist eine Sammlung von Metadaten, die Sie aus Node Instanzen erstellen können (ähnlich der gesamten Klassen-/Objekt-Beziehung).Generic Method Type Sicherheit

Ich habe verschiedene NodeType Implementierungen und verschiedene Node-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 ich die Methode implementieren wie dies:

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() vom Typ ThingType ungeprüft Umwandlung muss T vom Typ entsprechen AbstractNodeType

Was mache ich falsch um so eine Warnung zu verursachen?

Wie kann ich meinen Code re-Faktor, um dies zu beheben?

@SuppressWarnings("unchecked") ist nicht gut, ich möchte dies beheben, indem Sie es richtig codieren, nicht das Problem zu ignorieren!

Antwort

3

Sie können einfach ersetzen <T extends AbstractNode> T mit AbstractNode dank der Magie von covariant returns. Java 5 hinzugefügt Unterstützung, aber es erhielt nicht die Kneipe, die es verdient.

+0

Heilige Scheiße, das ist cool. Du hast recht, es bekommt wirklich nicht die Kneipe, die es verdient. – SCdF

+0

Ja, es ist das einzig Wertvolle, was ich aus diesem blöden SCJP-Buch herausgeholt habe. –

1

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(); 
    } 
} 
2

Zwei Möglichkeiten:

(a) Sie keine Generika verwenden. Es ist wahrscheinlich in diesem Fall nicht notwendig. (Obwohl die auf dem Code hängt havn't Sie gezeigt.)

(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(...); 
    } 
}