2011-08-25 48 views
2
public class Calculator<T> { 

    public Calculator(){ 

    } 

    public T calculateSum(T a,T b){ 
     return a; // I need to do something like a + b 
    } 
} 

我需要添加T對象,我限制T只能是數字類型。我怎樣才能做到這一點?Java 5泛型,如何獲取此示例工作

由於

+3

請發表你做了什麼來實現上述目標,這樣我們就可以糾正 – developer

回答

3

通用類型參數必須是參考的類型,其中不包括算術類型。您可以提供盒裝類型,如Integer作爲類型參數,但不會讓您進行算術運算,因爲自動拆箱僅適用於特定,特定裝箱類型。即使您將類型參數限制爲Number的後代,編譯器也不可能確定實際類型參數不是某個用戶定義的子類Number,它沒有任何自動拆箱行爲。

從技術上講,泛型類型不會讓你做任何你不能通過在非泛型代碼中插入向下(而不是其他)的代碼來實現的任何事情。在這裏,它看起來像你想要有一種不同的加法(整數或浮點),這取決於參數是哪種類型。而且無法通過插入演員來實現這一點。您必須插入一些明確的條件,測試值是否爲Integer,然後是Long,然後是Float等等。由於這比在這裏或那裏低調得多,因此原則上仿製藥不能爲你服務。

這與C++模板不同,其中模板的每個實例都在編譯器中生成(至少原則上)單獨的實現。

可以做的是使Calculator<T>一個抽象類或接口。然後製作具體的亞型,如

public class IntCalculator extends Calculator<Integer> { 
    public Integer calculateSum(Integer a, Integer b) { 
    return a+b; 
    } 
} 
public class DoubleCalculator extends Calculator<Double> { 
    public Double calculateSum(Double a, Double b) { 
    return a+b; 
    } 
} 

等等。

+0

感謝makholm,這是一個很好的解釋。 –

+0

我從未注意過Number是多少限制性數字。你甚至不能添加數字。 – toto2

0

在您的聲明中,您需要確保T始終是Number的子類型。

而不是

Calculator<T> 

嘗試

Calculator<T extends Number> 

然後查看java.lang.Number,你應該找到一種方式來獲得與+工作的價值。

+0

您是否需要知道T的具體類型以提取正確的值,例如: 'intValue()'? – Jiri

+2

這樣做的麻煩是沒有一個'Number'方法會總是提供完整的信息。'doubleValue()'可能會丟失位數,如果這個數字是'Long',當然'longValue()'會拋棄Double的小數部分。另外,即使可以使添加工作,也不可能構建要返回的類型參數的新實例。 –

+0

@亨寧Makholm,如果您知道該類型來自於一組有限的具體類型,RTTI可以在一定程度上提供幫助。有一條從字節到數字的可靠升級路徑。 –

1

方法(以及類)可以有類型參數。

public class Calculator { 

    public Calculator(){ 

    } 

    public <T extends Number > T calculateSum(T a,T b){ 
     return a; // I need to do something like a + b 
    } } 

此練習不需要泛型。

public class Calculator { 

    public Calculator(){ 

    } 

    public int calculateSum(int a,int b){ 
     return a + b ; 
    } 

    public long calculateSum(long a,long b){ 
     return a + b ; 
    } 

    .... you fill in the rest ... 
}