2008-12-11 41 views
8

我想定義泛型類型,其實際的類型參數只能是Java的形式類型參數定義(仿製藥)

  1. 一個數字基本類型的包裝類(LongIntegerFloatDouble
  2. String

我能滿足這樣的

定義的第一要求
public final class MyClass<T extends Number> { 
    // Implementation omitted 
} 

但我無法弄清楚如何滿足他們兩個。我懷疑這是不實際的,因爲據我所知沒有辦法來指定「或」定義形式類型參數時語義,雖然你可以使用一個定義如

public final class MyClass<T extends Runnable & Serializable > { 
    // Implementation omitted 
} 

乾杯, 唐註明「和」語義

+0

如果存在,類型擦除會將其放回對象。 – Loki 2008-12-11 20:48:50

回答

0

有趣的問題,它讓我有些不解。但顯然這是不可能的。我嘗試了幾種不同的黑客,沒有任何工作。

11

Java泛型不支持聯合類型(此參數可以是A或B)。

如果您想要強制執行多個限制,可能會對某些相關注釋感興趣,但它支持多個邊界。下面是從JDK在Java generics tutorial提到一個例子:

public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) 
+1

這不是一個壞例子(我看它來自SUN,不是你的)? >與>相同,是不是? 並不意味着什麼。 – Markus 2008-12-12 18:44:06

2

雖然仿製藥將在這裏工作,基本類型與派生類型NumberString意志。因爲無論如何,泛型類型已經被擦除到Object,所以你可能會在抽象基類中放置任何功能。您可能只需要子類上的特定於類型的訪問器即可獲取該值。

另外,請注意Number類。它不限於對原始類型進行裝箱,因爲任何人都可以對其進行擴展,例如BigInteger

4

您可以對所有支持的類型使用工廠方法,並使構造函數爲private/protected。你無論如何都要固定在構造函數中的泛型類型,這樣很有道理,所以你很可能這樣的代碼是:

public final class MyClass<T> { 
    public static MyClass<Integer> newInstance(int i) { 
     return new MyClass<Integer>(i); 
    } 
    public static MyClass<String> newInstance(String s) { 
     return new MyClass<String>(s); 
    } 
    //More factory methods... 

    protected MyClass(T obj) { 
     //... 
    } 
} 

或者,如果你不希望構造函數的參數,是這樣的: 公共決賽class MyClass public static MyClass newIntegerInstance(){ return new MyClass(); } // ... }

正如埃裏克森所說,共同實現只能在對象靠無論如何,所以唯一的限制是,你可以創建其他實現對其他類型除了原始和字符串。

0

也許你能做些什麼如下:

  1. MyClass<T>包,默認類,不可見的其他組件,或至少只能在包的默認構建函數,所以它不能擴展或外部的實例包。
  2. 在包的MyClass<T>創建兩個公共類:
MyNumericClass<T extends Number> extends MyClass<T> 
MyStringClass extends MyClass<String> 

這樣MyClass的所有子類將被限制在那些具有數子或字符串參數化。