簡體   English   中英

具有原始數據類型的Java模板作為C ++模板

[英]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.Integerjava.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM