2008-09-17 2 views
2

У меня есть концепция NodeType s и Node s. A NodeType - это куча метаданных, которые вы можете создать из Node экземпляров (много похожее на все отношения класса/объекта).Общий тип Тип Безопасность

У меня есть различные NodeType реализации и различные реализации узлов.

В моей AbstractNodeType (верхний уровень NodeTypes) У меня есть абы абстрактной createInstance() метода, после того, как реализован в подклассе, создает правильный экземпляр Node:

public abstract class AbstractNodeType { 
    // .. 

    public abstract <T extends AbstractNode> T createInstance(); 
} 

В моих NodeType реализациях я реализовать метод как это:

public class ThingType { 
    // .. 

    public Thing createInstance() { 
    return new Thing(/* .. */); 
    } 
} 

// FYI 
public class Thing extends AbstractNode { /* .. */ } 

Это все хорошо, но public Thing createInstance() создает предупреждение о безопасности типа. В частности:

безопасности Тип: возвращаемый тип Thing для CreateInstance() от типа ThingType необходимо беспрепятственное преобразование , чтобы соответствовать T от типа AbstractNodeType

Что я делаю неправильно вызвать такое предупреждение?

Как я могу переустановить мой код, чтобы исправить это?

@SuppressWarnings("unchecked") нехорошо, я хочу исправить это, закодировав его правильно, не игнорируя проблему!

ответ

3

Вы можете просто заменить <T extends AbstractNode> T на AbstractNode благодаря магии covariant returns. Java 5 добавлена ​​поддержка, но она не получила паб, который он заслужил.

+0

Святое дерьмо, что это круто. Вы правы, он действительно не получает паб, который держится! – SCdF 2008-09-17 10:23:34

1

Нечто подобное должно работать:

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

двумя способами:

(а) Не использовать дженерики. Вероятно, в этом случае это не обязательно. (Несмотря на то, что зависит от кода вы havn't показано на рисунке.)

(б) Generify AbstractNodeType следующим образом:

public abstract class AbstractNodeType<T extends AbstractNode> { 
    public abstract T createInstance(); 
} 
public class ThingType<Thing> { 
    public Thing createInstance() { 
    return new Thing(...); 
    } 
}