通用方法类型安全

时间:2020-03-05 18:58:29  来源:igfitidea点击:

我有NodeTypes和Nodes的概念。 NodeType是一堆元数据,我们可以从中创建Node实例(非常类似于整个Class / Object关系)。

我有各种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()会创建有关类型安全的警告。具体来说:

Type safety: The return type Thing for
  createInstance() from the type
  ThingType needs unchecked conversion
  to conform to T from the type
  AbstractNodeType

引起这种警告,我做错了什么?

如何重构我的代码以解决此问题?

@SuppressWarnings(" unchecked")不好,我希望通过正确编码来解决此问题,而不是忽略问题!

解决方案

回答

得益于协变返回的神奇性,我们只需用AbstractNode替换<Textended AbstractNode> T`。 Java 5增加了支持,但没有收到应有的发布。

回答

这样的事情应该起作用:

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

回答

两种方式:

(a)不要使用泛型。在这种情况下,可能没有必要。 (尽管这取决于我们未显示的代码。)

(b)生成AbstractNodeType如下:

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