通用构造函数的好处

9
什么是非泛型类具有通用构造函数的好处?Java规范允许以下内容:
class NonGeneric {
  <T> NonGeneric() { }
  ...
  NonGeneric ref = new <String> NonGeneric();
}

你能举出一个现实的例子来说明它如何增强类的类型安全性吗?相比于一开始就使用泛型,它有什么优势呢?

我理解Java设计者希望构造函数与方法更加一致。鉴于构造函数可能具有副作用,泛型构造函数可以使用泛型来改变一些不保留引用的参数,例如:

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

5
我能想到的唯一用途是,如果构造函数在运行时需要使用一个通用对象,但完成后并不存储该对象。
例如:
<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());
    }
}

很可能只是语言设计者为了以防万一而决定这样做,因为没有理由阻止人们这样做。


是的,它允许用构造函数替换通用方法(但你为什么要这样做呢?)。我从未在实际应用中看到过这种情况。对我来说,这是一种不必要的复杂性(就像C#后来引入其版本的Java泛型时所做的那样)。 - Tom Hawtin - tackline

0

是的,我也想过几次。

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

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

EntityRequestCallback extends RequestCallback

但是你希望RequestCallback是通用的RequestCallback<E extends Entity>,你不能这样做,因为只有PUT/POST请求使用Entity这两种类型。只有PUT/POST请求的构造函数包含Entity参数。

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;
    }
}

但是该类不能是通用的,因为您将为没有实体的请求创建RequestCallback,这意味着您将实例化

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

因此,这里唯一可能的方法是泛化:

EntityRequestCallback<E extends Entry> extends RequestCallback

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

public E entity;

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接