我尝试创建一个Variable
类,可以使用泛型来表示Integer
或Double
值。
以下是我尝试过的代码。由于擦除,我使用enum
来存储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>
时,我仍然会遇到同样的错误。
答案 0 :(得分:2)
您的架构似乎玷污了泛型的概念。
最简单的方法是在类型参数中设置上限:
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>
等。< / p>
答案 1 :(得分:1)
这里的问题是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;
}
答案 2 :(得分:0)
您收到错误是因为您在泛型类中表示了一个方法。你不能在T泛型类中定义一些。
顺便说一句,你误解了设计模式。
您必须为Variable设计一个泛型类,构造函数也必须将T作为参数类型。
在另一个类中,您使用createInteger和createDouble方法实现工厂。
答案 3 :(得分:0)
您可以使您的类继承自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
}
}
}
通过这种方式,没有特别需要为类型维护单独的枚举。