2009-10-24 75 views
1

我试图编写一个泛型类,它可以在任何简单类型(int,float等)上运行。我想避免几次重复相同的功能,改变参数的类型。但由于泛型参数是一个引用,所以我不能对它的类型变量进行任何计算,就像在C++模板中一样。Java泛型和简单类型

那么在Java中有什么简单的方法在泛型类型变量上使用算术运算符?我知道我可以使用类检查和投射,但我认为这将是更多的代码,并影响性能。不过,我最近才开始用Java写,所以我可能是错的。

回答

-1

的Java 1.5应通过autoboxing

+2

我认为这个问题是关于泛型。如果你定义了一个方法'T foo (T value)',你不能做任何算术运算。自动装箱在这里没有帮助。 – tangens 2009-10-24 12:21:48

2

一个解决办法处理这个问题你可能会使用一个模板方法:

T foo<T extends Number>(T value) 

,并通过使用value.intValue()value.longValue()value.doubleValue()做计算。

+0

但你怎么知道使用哪个value.someValue()方法?做一个实例检查价值本身?这只是同样的问题,转移到代码中的不同位置。决定返回什么类型的难度相同。 – 2015-06-16 23:01:24

+0

如果有人通过BigDecimal会怎么样?那些方法完全失败。 – 2015-06-16 23:03:22

3

有没有办法做到这一点你将如何在C + +,对不起。 Java中的泛型与C++模板的工作方式截然不同。在Java中,只生成一个通用代码版本,它必须适用于所有类型参数。因为所有的原语在字节码中都有不同的表示,所以它们不能共享相同的通用码。这就是为什么只有引用类型是Java中的有效类型参数。

我认为最接近你会得到的将是使用Number类。自动装箱会自动将任何原始数值转换为Number的子类。例如:

class Foo<T extends Number> { 
    public void operate(T number) { 
    double value = number.doubleValue(); 
    // do something with the double 
    } 
} 
Foo<Integer> intFoo = new Foo<Integer>(); 
intFoo.operate(666); 
intFoo.operate(666.0); // fails to compile 

但是,类型参数并不真的买你很多。如果你想operate方法返回一个T类型的值,你必须求助于运行时检查,哪种方式会失败。

一个可能有趣的边注:Scala 2.8将支持一个注解@specialize基本上告诉编译器“处理类型参数的C++方式”,并且产生用于每个不同类型的自变量表示一个不同的版本的代码。