2009-08-19 33 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; 

在这个特定的例子中,泛化是正确的选择,但有些情况下泛化不会。