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

带有静态工厂方法的Java泛型,java,generics,Java,Generics,我正在尝试创建一个变量类,该类可以使用泛型表示整数或双精度值 下面是我尝试过的代码。由于擦除,我使用枚举来存储变量的预期类型,然后尝试使用它将值初始化为正确的类型 public class Variable<T> { private enum Type {INTEGER, DOUBLE}; private Type type; private T value; public static Variable<Integer> c

我正在尝试创建一个
变量
类,该类可以使用泛型表示
整数
双精度

下面是我尝试过的代码。由于擦除,我使用
枚举
来存储
变量
的预期类型,然后尝试使用它将值初始化为正确的类型

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

}
同样地,对于
Double

有人能解释为什么会发生这种情况吗?如果有一种方法可以绕过这种情况,而不必编写两个单独的类,一个用于
Integer
,另一个用于
Double

编辑 谢谢你所有的回答…基于这些,我现在意识到有更好的方法可以做到这一点。然而,我试图弄清楚为什么这种方法不起作用,这样我以后就不会犯同样的错误


当我按照建议将类定义为
公共类变量
时,仍然会出现相同的错误。

之所以会出现错误,是因为您在泛型类中键入了一个方法。不能在t泛型类中定义一些

顺便说一句,你弄错了设计模式

您必须为变量设计泛型类,并且构造函数必须将T作为参数类型


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

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

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

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

否则,您可以确保使用
private
构造函数,并提供
static createAs…
非泛型方法,如
createAsInteger
等,该方法将返回
新变量
等。

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

String value = new Integer(0);

您可以这样布置工厂方法:

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

您可以使类从数字继承,并使用类型检查为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
               }

     }
}
公共类变量{
公共静态变量创建(变量var){
if(var instanceOf Integer){
//采取适当行动
}
else if(变量instanceOf Double){
//采取适当行动
}
}
}

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

如果不检查类变量,实际上不需要
Class clazz
static Variable create()
works.@AndyTurner您当然是对的。
clazz
参数只允许细粒度地控制
数字可以是或不能是什么。不过我会编辑答案。我以前在方法声明中没有遇到过这两组菱形运算符,即
变量
。你能推荐一些我能读到更多关于这些的链接吗?@soarjay这表明了一个问题。它的类型参数独立于泛型类中的类型参数,因此将其作为静态工厂方法非常有用。同样在构造函数中,我需要通过调用
new Integer(0)
new Double(0)
值初始化为零,这正是我遇到的困难!
if (!clazz.equals(Integer.class) && !clazz.equals(Double.class)) {
    // TODO complain
}
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;
}
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
               }

     }
}