我可以强制构造函数对其泛型类型设置更严格的限制吗?

时间:2019-03-20 11:02:39

标签: java generics constructor type-bounds

在Java中,泛型类具有用于构造某些泛型类型的实例的构造函数。这很简单,构造函数的调用者可以指定范围内的任何类型。

是否可以有一个构造函数对该泛型类型进行更严格的限制?
例如,有一个强制将通用类型设为String的构造函数。

public class GenericClass<T extends Serializable> {
    public GenericClass() {
        // normal constructor
    }

    public GenericClass(String argument) {
        // Can I force this constructor to construct a `GenericClass<String>`?
    }
}

// The first constructor can have any type
GenericClass<String> stringInstance = new GenericClass<>();
GenericClass<Integer> intInstance = new GenericClass<>();

// The second constructor is limited to `GenericClass<String>`
stringInstance = new GenericClass<>("with generic type String is okay");
intInstance = new GenericClass<>("with other generic type is not okay");

我想让最后一行由于类型不兼容而失败。

这可能吗?

2 个答案:

答案 0 :(得分:3)

public GenericClass(String argument)

问题在于,编译器应该如何知道StringT?参数与泛型类型参数之间没有链接,也无法指定一个。您可以使用

public GenericClass(T argument)

并使用

进行构建
new GenericClass<>("foo");

但这将允许GenericClass用任何类型的对象实例化。

您可以使用继承大致实现所需的功能,尽管您需要引入第二个类:

class GenericClass<T extends Serializable> {
    public GenericClass() {

    }
}

class StringClass extends GenericClass<String> {
    public StringClass(String argument) {

    }
}

如果要避免使用继承,则可以引入一个接口并使两个类都实现该接口。那就是我要做的。

答案 1 :(得分:2)

导致最后一行失败的一种方法是:

public class GenericClass<T extends Serializable> {
    public GenericClass() {
        // normal constructor
    }

    public GenericClass(T argument) {

    }
}

但是显然,这并不能阻止人们致电new GenericClass<>(1)

或者,您可以编写工厂方法ofString

public static GenericClass<String> ofString(String s) {
    GenericClass<String> gc = new GenericClass<>();
    // do stuff to gc
    return gc;
}