Вопрос

У меня есть концепция NodeTypeы и Nodes.A NodeType это набор метаданных, которые вы можете создать Node экземпляры из (очень похоже на отношения между классом и объектом в целом).

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

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

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") это нехорошо, я хочу исправить это, правильно закодировав его, а не игнорируя проблему!

Это было полезно?

Решение

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

Другие советы

Два способа:

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

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

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

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

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();
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top