如何实例化一个使用给定double值扩展Number的泛型类?

时间:2015-11-29 18:59:20

标签: java generics

假设我有这个Foo类,它具有扩展E的泛型类型变量Number。由于每个Number对象应该具有double值,因此在实例化类型E的新实例时,我想给它一个double值。可能吗?怎么样?

public class Foo<E extends Number> {
    ...
    public void someMethod() {
        ... // some computation
        Class<E> typeClass;
        E newInstance = typeClass.newInstance();
        // Because every Number has a doubleValue(),
        // I would like to give newInstance a double value, how?
    }
}

或者我应该放弃泛型类型变量,而是使用Double代替?但我不想限制用户使用ByteInteger的自由。这些数字类是否可以互换,即可以Byte以某种方式转换为Double

谢谢!

编辑:

我正在使用泛型实现Dijkstra算法,该算法计算最小加权路径。这意味着边缘标签可以以某种方式累积,为此我可以想到的最通用的类​​是Number

1 个答案:

答案 0 :(得分:1)

首先,你的假设是

  

由于每个Number对象都应该具有double值,因此在实例化E类型的新实例时,我想给它一个double值。

不正确。

例如,如何使用double值1.5实例化Integer?它应该通过舍入来实例化吗?通过截断?我可以很好地定义Number的子类,它甚至不支持任意整数,如下所示:

public static class Zero extends Number {
    @Override
    public double doubleValue() {
        return 0;
    }

    @Override
    public float floatValue() {
        return 0;
    }

    @Override
    public int intValue() {
        return 0;
    }

    @Override
    public long longValue() {
        return 0;
    }
}

如何使用像1.5这样的双精度值实例化零?

由于没有通用逻辑可以使用任意双值实例化Number的任意子类(这就是为什么Number不具有带双参数的构造函数的原因),唯一合理的方法是询问客户端提供一个工厂,它可以使用适用于该特定子类的自定义逻辑给定一个任意double值的Number子类的实例。如下所示:

  public class Foo<E extends Number> {

    public static interface NumberFactory<T extends Number> {
        T createByDoubleValue(double value);
    }

    private final NumberFactory<E> factory;

    public Foo(NumberFactory<E> factory) {
        this.factory = factory;
    }

    ...
    public void someMethod() {
      ... // some computation
      // Because every Number has a doubleValue(),
      // I would like to give newInstance a double value, how?
      E instance = factory.createByDoubleValue(1.5);
    }
  }

要使用Foo类,客户端需要定义工厂,如下所示:

Foo<Float> foo = new Foo<>(new Foo.NumberFactory<Float>() {
  @Override
    public Float createByDoubleValue(double value) {
      return new Float(value);
    }
});