[英]Return type generic
我正在学习在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”
有任何想法吗?
那不是它的工作原理。 泛型类型并不意味着“我不知道我将返回什么,我们将根据所得到的来查看,这可能是依赖于实现的列表中的任何内容”。 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();
}
}
注意,最好重用现有接口,例如
UnaryOperator<Integer> intInverter = i -> -i.intValue();
UnaryOperator<Boolean> boolInverter = b -> !b.booleanValue();
编辑:@Twometer的建议将导致类似
class Inverters {
public static UnaryOperator<Integer> integerInverter() {
return i -> -i.intValue();
}
public static UnaryOperator<Boolean> boolInverter() {
return b -> !b.booleanValue();
}
// and maybe even this, but this will still require a cast
// at the client
public static <T> UnaryOperator<?> inverter(Class<T> clazz) {
if (clazz == Integer.class) {
return integerInverter();
} else if (clazz == Boolean.class) {
return boolInverter();
}
throw new IllegalArgumentException(String.format("Cannot create inverter for class %s", clazz));
}
}
这样,您就可以集中获得所需的逆变器。 这样,您确定它们将被重用。 此外,您可以缓存创建的lambda,而不必更改客户端代码。
仅当要区分的两个类具有(有用的)公共超类时,泛型才有帮助。 但是, Boolean
和Integer
的第一个通用超类是Object
,它没有用。
如果您的目标是学习泛型,我建议使用例如 Integer
和Double
两者,它们确实具有共同的子类Number
,因此您可以将T
定义为T extends Number
如果您的目标与您的示例完全相同,则可以按照@daniu的回答进行操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.