简体   繁体   English

通用方法类型安全

[英]Generic Method Type Safety

I have the concept of NodeType s and Node s. 我有NodeTypeNode的概念。 A NodeType is a bunch of meta-data which you can create Node instances from (a lot like the whole Class / Object relationship). NodeType是一堆元数据,您可以从中创建Node实例(非常类似于整个Class / Object关系)。

I have various NodeType implementations and various Node implementations. 我有各种NodeType实现和各种Node实现。

In my AbstractNodeType (top level for NodeTypes) I have ab abstract createInstance() method that will, once implemented by the subclass, creates the correct Node instance: 在我的AbstractNodeType(NodeTypes的顶层)中,我有一个abstract createInstance()方法,该方法一旦由子类实现,将创建正确的Node实例:

public abstract class AbstractNodeType {
  // ..

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

In my NodeType implementations I implement the method like this: 在我的NodeType实现中,我实现了如下方法:

public class ThingType {
  // ..

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

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

This is all well and good, but public Thing createInstance() creates a warning about type safety. 一切都很好,但是public Thing createInstance()创建了有关类型安全的警告。 Specifically: 特别:

Type safety: The return type Thing for createInstance() from the type ThingType needs unchecked conversion to conform to T from the type AbstractNodeType 类型安全性:ThingType类型的针对createInstance()的返回类型Thing需要未经检查的转换才能符合AbstractNodeType类型的T

What am I doing wrong to cause such a warning? 引起这种警告,我做错了什么?

How can I re-factor my code to fix this? 如何重构我的代码以解决此问题?

@SuppressWarnings("unchecked") is not good, I wish to fix this by coding it correctly, not ignoring the problem! @SuppressWarnings("unchecked")不好,我希望通过正确编码来解决此问题,而不是忽略问题!

You can just replace <T extends AbstractNode> T with AbstractNode thanks to the magic of covariant returns . 只需更换<T extends AbstractNode> TAbstractNode感谢神奇的协变的回报 Java 5 added support, but it didn't receive the pub it deserved. Java 5增加了支持,但没有收到应有的发布。

Two ways: 两种方式:

(a) Don't use generics. (a)不要使用泛型。 It's probably not necessary in this case. 在这种情况下,可能没有必要。 (Although that depends on the code you havn't shown.) (尽管这取决于您未显示的代码。)

(b) Generify AbstractNodeType as follows: (b)生成AbstractNodeType如下:

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

Something like that should work: 这样的事情应该起作用:

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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM