在Java中限制泛型类

时间:2011-11-15 20:21:27

标签: java generics

我有一个运算符类,其中包含一些处理数学运算的类和方法。运算符类是通用的并且扩展了Number,所以我的操作可以是int,double,float等。

public class OperatorClass<T extends Number>

在这个类中有一个抽象类,它提供了一种使用calculate方法

操作数字的方法
abstract class Op<T extends Number> {
    abstract T calculate(DataSet<? extends Number> ds);
}

有多个类像AddOp一样扩展Op,例如:

class AddOp<T extends Number> extends Op<T>{
    public T calculate(DataSet<? extends Number> ds) {
        return ds.getLeft() +  ds.getRight();
    }
}

我的DataSet只是一个如下所示的数据类:

public class DataSet<T extends Number> {
private T left;
private T right;

public DataSet(T left, T right) {
    this.left = left;
    this.right = right;
}

public T getLeft() {
    return left;
}
public T getRight() {
    return right;
}

}

我遇到的问题是行ds.getLeft() + ds.getRight()没有编译,因为Number抽象类不能执行+运算符。我如何让我的DataSet成为一种Number(就像一个通配符类),所以我可以对它进行数学运算。

任何帮助将不胜感激 感谢

修改

问题的解决方法是我使用了一些if语句然后得到了正确的原始数据类型

Number result = null;
if(ds.getLeft().getClass().equals(Integer.class))
     result = new Integer(ds.getLeft().intValue() + ds.getRight().intValue());
....
return (T) result;

3 个答案:

答案 0 :(得分:1)

您必须决定要添加的分辨率。换句话说,您是在呼叫left.getInteger()还是left.getFloat()

有很多方法可以解决这个问题,但它实际上归结为你打算做什么。如果您希望您的数字真正保留为对象,则不能使用+ plus运算符,因为它不适用于对象。您需要left.plus(right)样式方法调用,该方法将返回一个新数字。

如果你不关心在数学练习期间将你的数字保存为对象(可能它们只是为了收集存储或其他东西),那么你将public T getLeft()替换为public long getLeft()并依赖在内部编号left.getLongValue()上进行转换。或者您只是展示两个Number对象,并允许“外部”用户执行相应的getXxxValue()调用。

答案 1 :(得分:0)

数字类型是基本类型,您不能通过它们实现算术运算。 Java的泛型不像C ++模板那样工作,也不生成特定于类型的代码,并且无法添加两个Number实例或任何其他原始包装类型的实例。

您在Java中尝试做的事情是不可能的,您必须为intdoubles等编写单独的方法(或者您想要支持的任何方法。)

答案 2 :(得分:0)

不能在Java中重载运算符。最简单的是改变:

    return ds.getLeft() +  ds.getRight();

to(类似)

    return ds.getLeft().getDouble() +  ds.getRight().getDouble();

我说类似,因为你可能需要处理一点类型的转换。

认为还有其他方法getFloat() getInt()...我选择了双倍,因为截断不会有任何损失。