[英]Java template with primitivedata types as C++ templates
我想使用模板/泛型在Java中實現功能,就像在C ++中一樣。 我試圖在Java中使用具有原始值(int,double,...)的泛型,但是對於下面的函數,我從編譯器中收到以下錯誤:
錯誤:二進制運算符'+'sum + = value的操作數類型錯誤; 第一類型:雙第二類型:T其中T是類型變量:T擴展了在方法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活動!)更“糟糕”的了
Java中不能具有帶有原始類型參數的泛型函數。
您可以使用帶框的原語( java.lang.Integer
, java.lang.Double
等)以及所有這些類都實現java.lang.Number
接口的事實來近似求解。
使用數組的解決方案:
private static <T extends Number> double mean(T[] data) {
double sum = 0;
for (T number : data)
sum += number.doubleValue();
return sum / data.length;
}
public static void main(String[] args) {
Double[] data = new Double[] {12.0, 16.0};
System.out.println(mean(data));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.