我想像在 C++ 中一样使用模板/泛型在 Java 中实现一个函数。我尝试在 Java 中使用具有原始值(int、double 等)的泛型,但是对于下面的函数均值,我从编译器中得到以下错误:
error: bad operand types for binary operator '+' sum += value; first type: double second type: T where T is a type-variable: T extends Object declared in method mean(T[])
我尝试用其他值替换 T,但找不到答案。正确的做法是什么?
// Java code
private <T> double mean(T[] data) {
double sum = 0;
for (T value : data)
sum += value;
return sum / data.length;
}
最佳答案
简单地说:你不能。
与 C++ 模板相比; Java 泛型仅适用于引用,也就是“对象”类型。不,没有办法解决这个问题。
这里的关键是:Java 泛型与 C++ 模板不是一回事。
在 C++ 方面,编译器实际上是从您的模板中创建特定于类型的代码。对于 java,泛型(不过是)语法糖 围绕采用Object 参数的方法。换句话说:编译器进行所有转换,使其看起来像您的 List<String>
真的只适用于字符串。但是 List<String>
没有特殊/不同的编译单元或 List<Integer>
.只有一个 List.class 可以在所有地方使用 Object。
所以基本的答案是:两个概念在两种不同的编程语言中在句法上看起来是相同的这一事实......并不能使它们在语义上相同。
记录在案:正如其他答案所建议的那样,您可以使用类似 <T extends Number>
的内容另一剂语法糖(称为自动装箱和拆箱)开始发挥作用。但要注意后果:自动装箱基本上转化为:中间 Long、Integer 等对象的创建。换句话说:广泛使用,会对性能产生主要影响(例如,在处理具有原始值的非常大的数组时);因为没有什么比创建大量立即变成“垃圾”(并因此触发 GC Activity !)的对象“更糟糕”的了!
关于具有原始数据类型的 Java 模板作为 C++ 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41060384/