Универсальный метод Тип безопасности - PullRequest
2 голосов
/ 17 сентября 2008

У меня есть понятия NodeType с и Node с. NodeType - это набор метаданных, из которых вы можете создавать Node экземпляры (во многом как отношения класса / объекта).

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

В моем 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 for createInstance () из типа ThingType нуждается в непроверенном преобразовании соответствовать Т от типа AbstractNodeType

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

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

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

Ответы [ 3 ]

3 голосов
/ 17 сентября 2008

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

2 голосов
/ 17 сентября 2008

Два способа:

(а) Не используйте дженерики. Это, вероятно, не нужно в этом случае. (Хотя это зависит от кода, который вы не показывали.)

(b) Генерируйте AbstractNodeType следующим образом:

public abstract class AbstractNodeType<T extends AbstractNode> {
  public abstract T createInstance();
}
public class ThingType<Thing> {
  public Thing createInstance() {
    return new Thing(...);
  }
}
1 голос
/ 17 сентября 2008

Что-то подобное должно работать:

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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...