【问题标题】:Java: Using generics to implement a class that operates on different kinds of numbersJava:使用泛型实现对不同类型数字进行操作的类
【发布时间】:2008-11-12 23:12:36
【问题描述】:

所以,假设我想编写一个对不同类型的数字进行操作的类,但我事先不知道我将在哪些类型的数字(即整数、双精度数等)上进行操作。

我想使用泛型为这个场景创建一个通用类。比如:

 Adder<Double> adder = new Adder<Double>();
 adder.add(10.0d, 10.0d);   // = 20.0d

但是,我无法实例化传递给 Adder 类的泛型类型!那么——该怎么办?

【问题讨论】:

  • 我假设 Adder 将被声明为 class Adder,在这种情况下,您的“add”方法实现将只有 Number API 可以使用。您打算如何使其对所有 Number 对象正常工作?添加 BigInteger 的实现不适用于添加 double。
  • 一个小问题:Short i = (short)20000; i+i 是什么?机器代码风格的算术是讨厌的。忍受它。或者确保下一种语言更智能。

标签: java generics


【解决方案1】:

呃哦---泛型不是 C++ 模板。由于类型擦除,您示例中的 Double 甚至不会显示给运行时系统。

在您的特定情况下,如果您只想能够将各种类型添加在一起,我可以建议方法重载吗?例如,double add(double, double)float add(float, fload)BigDecimal add(BigDecimal, BigDecimal)

【讨论】:

  • 0 投反对票 谢谢,克里斯。但是,说真的,我有一个大类需要对不同类型的数字执行相同的(大量)操作。你是说我又回到了复制粘贴?
【解决方案2】:

认为你可以做你想做的,但我不确定,鉴于你提供的信息。听起来好像您想要以下内容的一些变体:

public class Foob<T extends Number> {

    public T doSomething(T t1, T t2) {
        return null;
    }
}

【讨论】:

    【解决方案3】:

    如果您不知道要对哪些类型的数字进行运算,那么您可能不会使用自己的实例变量。在这种情况下,您可以编写静态方法,而无需实例化您的类。

    如果您确实需要自己的中间变量,那么您可能需要为您正在使用的每一类用户变量分别定义它们。例如,如果有人试图使用您的类来操作 BigDecimal 变量,您可能不会使用 int 变量来获得中间结果。

    【讨论】:

      【解决方案4】:

      我不确定泛型是您想要的。 Java 中的泛型用于强制执行编译时 约束,而不是运行时多态性。我认为你真正想要的是使用重载。使用泛型,你会得到类似的东西:

      interface Adder<T> {
         T add(T arg1, arg3);
      }
      

      还有一堆:

      class DoubleAdder implements Adder<Double> {
         Double add(Double arg1, Double arg2) {
            return arg1.add(arg2);
         }
      }
      

      然后是一堆:

      if (arg1 instanceof Double) {
         Adder<Double> adder = new DoubleAdder();
      }
      

      使用泛型并不能为您节省任何费用。

      【讨论】:

        【解决方案5】:

        我同意拉普利的观点。重载对你有帮助。使用泛型最接近的是这样的:

        公共类 NumericOps
        {
        公共 T add(T n1, T n2) {
        //n1.add(n2);
        //这是不可能的,因为Number没有add方法,因此
        //您必须确定 n1 的类型。
        //我们无法确定U的类型,因为它在运行时不会存在
        //由于类型擦除
        if(n1 instanceof Integer) {
        //添加整数...
        }
        else if(n1 instanceof Double) {
        //添加双打
        }
        返回空值;
        }
        }

        但这并没有太大帮助,因为使用泛型没有任何好处。

        【讨论】:

          【解决方案6】:

          如果您可以忍受将所有内容转换为双精度进行计算,您可以使用多态性

          Number someNumberFunction(Number n1, Number n2) 
          {
            double
                d1 = n1.doubleValue(),
                d2 = n2.doubleValue();
          
            /* perform computations on d1 & d2 */
          }
          

          很遗憾,这不适用于 BigInteger 或 BigDecimal

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多