繁体   English   中英

带有静态工厂方法的Java泛型

[英]Java Generics with Static Factory methods

我正在尝试创建一个可以使用泛型表示一个IntegerDouble值的Variable类。

下面是我尝试过的代码。 由于擦除,我使用一个enum来存储Variable的预期类型,然后尝试使用该Variable将值初始化为正确的类型。

public class Variable<T> {

    private enum Type {INTEGER, DOUBLE};
    private Type type;

    private T value;

    public static Variable<Integer> createAsInteger() {
        return new Variable<Integer>(Type.INTEGER);
    }

    public static Variable<Double> createAsDouble() {
        return new Variable<Double>(Type.DOUBLE);
    }

    private Variable(Type type) {
        this.type = type;

        if(type == Type.INTEGER) {
            value = new Integer(0);
        } else {
            value = new Double(0.0);
        }
    }

    public static void main(String[] args) {
        Variable.createAsInteger();
        Variable.createAsDouble();
    }

}

但是,当我编译它时,我收到以下消息...

error: incompatible types: Integer cannot be converted to T
                    value = new Integer(0);

对于Double

谁能解释为什么会这样,如果有办法解决这个问题而不必编写两个单独的类,一个用于Integer ,一个用于Double

编辑

感谢您的所有回答...基于它们,我现在意识到有更好的方法可以做到这一点。 但是,我试图弄清楚为什么这种方法行不通,以便将来我不会再犯同样的错误。

当我按照建议public class Variable<T extends Number>定义为public class Variable<T extends Number> ,仍然遇到相同的错误。

您的体系结构似乎to污了泛型的概念。

最简单的方法是在类型参数中设置上限:

class Variable<T extends Number> {...}

然后,您可以使用通用的工厂方法根据所需的类创建Variable<X>

static <X extends Number>Variable<X> create() {
    return new Variable<X>();
}

然后可以按以下方式调用它:

Variable.<Integer>create(); // returns an instance of `Variable<Integer>`

这将不限于IntegerDouble ,而是任何Number

如果有必要,可以通过执行以下操作来限制这些选择:

  • 向您的create方法添加一个参数: create(Class<X> clazz)
  • 检查方法主体中clazz参数的值:

     if (!clazz.equals(Integer.class) && !clazz.equals(Double.class)) { // TODO complain } 

否则,您可以确保使用private构造函数并提供static createAs...非泛型方法(例如createAsInteger等),这些方法将返回new Variable<Integer>等。

这里的问题是T可以是任何东西。 如果T例如是String ,您的代码将为:

String value = new Integer(0);

您可以这样设计工厂方法:

public static Variable<Integer> createAsInteger() {
    return new Variable<>(new Integer(0), Type.INTEGER);
}

在哪里有类似的构造函数:

private Variable(T value, Type type) {
    this.value = value;
    this.type = type;
}

因为在通用类中正在对方法进行类型化,所以会出现错误。 您不能在T泛型类中定义某些内容。

顺便说一下,您正在误用设计模式。

您必须为Variable设计一个通用类,构造函数也必须将T作为参数类型。

在另一个类中,可以使用createInteger和createDouble方法实现工厂。

您可以使您的类从Numbers继承,并使用类型检查为Integer或Double调用适当的方法。

public class Variable<T extends Number> {
     public static Variable<T extends Number> Variable<T> create(Variable<T> var){
               if (var instanceOf Integer){
                // Take appropriate action
               }
               else if (var instanceOf Double){
               // Take appropriate action
               }

     }
}

这样,就不需要为Types维护单独的枚举。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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