通用构造函数的好处

时间:2009-08-19 13:44:30

标签: java generics polymorphism

为非泛型类设置泛型构造函数有什么好处? 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
}

2 个答案:

答案 0 :(得分: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());
    }
}

语言设计师最有可能只是为了某些人想要它而做的事情,因为没有理由阻止人们这样做。

答案 1 :(得分:0)

是的,我几次都在考虑这个问题。

假设(有xx原因,为什么它不是这样的)如果通用构造函数可以为整个类定义正式泛型类型(如泛型类声明那样)会很好......也就是说,如果定义Generic构造函数会让你在该类中有通用字段...

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

EntityRequestCallback extends RequestCallback

但是你希望RequestCallback是通用的RequestCallback<E extends Entity>,你不能这样做,因为只有两种类型的请求PUT / POST使用Entity。只有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;
    }
}

但是这个类不能是通用的,因为你要为没有实体的Request创建RequestCallback,这意味着你要实例化

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

因此,这里唯一可行的方法是概括:

EntityRequestCallback<E extends Entry> extends RequestCallback

这样你就可以拥有通用字段:

public E entity;

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