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泛型,如何獲取此示例工作
由於
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泛型,如何獲取此示例工作
由於
通用類型參數必須是參考的類型,其中不包括算術類型。您可以提供盒裝類型,如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;
}
}
等等。
感謝makholm,這是一個很好的解釋。 –
我從未注意過Number是多少限制性數字。你甚至不能添加數字。 – toto2
在您的聲明中,您需要確保T
始終是Number
的子類型。
而不是
Calculator<T>
嘗試
Calculator<T extends Number>
然後查看java.lang.Number
,你應該找到一種方式來獲得與+
工作的價值。
您是否需要知道T的具體類型以提取正確的值,例如: 'intValue()'? – Jiri
這樣做的麻煩是沒有一個'Number'方法會總是提供完整的信息。'doubleValue()'可能會丟失位數,如果這個數字是'Long',當然'longValue()'會拋棄Double的小數部分。另外,即使可以使添加工作,也不可能構建要返回的類型參數的新實例。 –
@亨寧Makholm,如果您知道該類型來自於一組有限的具體類型,RTTI可以在一定程度上提供幫助。有一條從字節到數字的可靠升級路徑。 –
方法(以及類)可以有類型參數。
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 ...
}
請發表你做了什麼來實現上述目標,這樣我們就可以糾正 – developer