2009-08-19 62 views
9

爲非泛型類使用泛型構造函數有什麼好處? Java規範允許以下內容:通用構造函數的好處

class NonGeneric { 
    <T> NonGeneric() { } 
    ... 
    NonGeneric ref = new <String> NonGeneric(); 
} 

可以想出什麼時候它會增強類的類型安全嗎?如何比首先使用Generic更好?

我明白,Java設計師希望構造函數更加符合方法。 由於構造函數可以有副作用,一般的構造函數可以使用泛型變異一些參數,其引用不保留,如

<T> NonGeneric(T obj, List<T> list) { 
    list.add(obj); 
    // Don't hold a reference to list 
} 

回答

4

,我能想到的唯一用途如果構造需要將在運行時使用通用對象,但一旦完成就不存儲該對象。

例如:

<T> NonGeneric(T[] blank, List<T> list) { 
    // Sort that list 
    T[] array = list.toArray(blank); 
    Arrays.sort(array); 

    // Pull out the values as strings 
    this.list = new ArrayList<String>(array.length); 
    for (T value : array) { 
     this.list.add(value.toString()); 
    } 
} 

這是最有可能只是一些語言設計者決定做以防萬一有人想它,因爲沒有理由阻止人們這樣做。

+0

是的,它允許泛型方法被構造函數替換(但爲什麼你會想?)。我從來沒有真正看到過野外。對我的錢來說,這種語言可能沒有做到這一點很複雜(正如C#在稍後介紹其Java版本的泛型時所做的那樣)。 – 2009-08-19 15:14:18

0

是的,我在想同樣的幾次。

假設(有xx的原因爲什麼它不是這樣)如果泛型構造函數可以爲整個類定義正式泛型類型(就像泛型類聲明一樣),那將是很好的......也就是說,如果定義通用構造將讓你在這個類通用領域...

例如,如果你想避免泛化:

EntityRequestCallback extends RequestCallback 

,但你想要的RequestCallback是通用RequestCallback<E extends Entity>,你可以這樣做因爲只有兩種類型的請求PUT/POST使用實體。只有PUT/POST請求的構造函數包含實體參數。

public class RequestCallback { 

     /** GET/DELETE requests */ 
    public RequestCallback(String gttUrl, HttpMethod method,) { 
     this.gttUrl = gttUrl; 
       this.method = method; 
    } 

     /** PUT/POST requests */ 
    public RequestCallback(String gttUrl, HttpMethod method, Entity entity) { 
     this.gttUrl = gttUrl; 
       this.method = method; 
     this.entity = entity; 
    } 
} 

但類不能通用,因爲你會爲沒有一個實體,這意味着你會實例

new RequestCallback(); //without specifying generic parameter - worse than nothing 

請求要創建RequestCallback使這裏的唯一可能的途徑是概括:

EntityRequestCallback<E extends Entry> extends RequestCallback 

所以,你可以有通用字段:

public E entity; 

在這個特定的例子中,泛化是正確的選擇,但有些情況下泛化不會。