返回类型通用

时间:2018-12-12 09:12:06

标签: java generics

我正在学习在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”

有什么想法吗?

2 个答案:

答案 0 :(得分:6)

这不是它的工作方式。泛型类型并不意味着“我不知道我将返回什么,我们将根据所得到的来查看,这可能是依赖于实现的列表中的任何内容”。 wwwroot类型可能是可变的,但只能在实现时使用-在运行时,它是固定的,并且是TBoolean

所以你可以做的

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)

泛型仅在要区分的两个类具有(有用的)公共超类时才有用。但是BooleanInteger的第一个通用超类是Object,这没有用。

如果您的目标是学习泛型,建议您使用 eg IntegerDouble,它们都具有相同的子类Number,因此您可以定义TT extends Number

如果您的目标与您的示例完全一样,那么您可以按照@daniu的回答进行操作。