我正在学习在Java中使用泛型,并且我需要以下函数(在具有泛型属性的类中可以工作:
public T evaluate() {
if (arg.getValue() instanceof Boolean) {
return !arg.getValue();
} else if (arg.getValue() instanceof Integer) {
return -arg.getValue();
}
}
该类具有类型为Expression的属性arg。 arg.getValue返回类型T的变量。如果T是布尔值,则函数评估应返回arg.getValue的逻辑取反,如果T是整数则返回-arg.getValue的逻辑取反。它不会编译,因为-和!运算符“不能应用于T”。
另一种选择是实施以下想法:
public T evaluate() {
if (arg.getValue() instanceof Boolean) {
Boolean b = (Boolean) arg.getValue();
Boolean r = new Boolean(!b);
return r;
} else if (arg.getValue() instanceof Integer) {
Integer i = (Integer) arg.getValue();
Integer r = -i;
return r;
}
}
但是那样返回是无效的:“必需的不兼容类型:T找到:java.lang.Boolean / Integer”
有什么想法吗?
答案 0 :(得分:6)
这不是它的工作方式。泛型类型并不意味着“我不知道我将返回什么,我们将根据所得到的来查看,这可能是依赖于实现的列表中的任何内容”。 wwwroot
类型可能是可变的,但只能在实现时使用-在运行时,它是固定的,并且是T
或Boolean
。
所以你可以做的
Integer
实现方式
public interface Inverter<T> {
// variable return type, depending on argument
T invert(T toInvert);
}
请注意,最好重用现有接口,例如
class IntegerInverter implements Inverter<Integer> {
// return type is fixed to integer
Integer invert(Integer toInvert) {
return -toInvert.intValue();
}
}
class BooleanInverter implements Inverter<Boolean> {
// return type is fixed to boolean
Boolean invert(Boolean toInvert) {
return !toInvert.booleanValue();
}
}
编辑: @Twometer的建议将导致类似
UnaryOperator<Integer> intInverter = i -> -i.intValue();
UnaryOperator<Boolean> boolInverter = b -> !b.booleanValue();
这样,您就可以集中获取所需的逆变器;这样,您确定它们将被重用。另外,您可以缓存创建的lambda,而无需更改客户端代码。
答案 1 :(得分:1)
泛型仅在要区分的两个类具有(有用的)公共超类时才有用。但是Boolean
和Integer
的第一个通用超类是Object
,这没有用。
如果您的目标是学习泛型,建议您使用 eg Integer
和Double
,它们都具有相同的子类Number
,因此您可以定义T
为T extends Number
如果您的目标与您的示例完全一样,那么您可以按照@daniu的回答进行操作。