[英]Java Generics with Static Factory methods
我正在尝试创建一个可以使用泛型表示一个Integer
或Double
值的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>`
这将不限于Integer
和Double
,而是任何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.