在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");
我想让最后一行由于类型不兼容而失败。
这可能吗?
答案 0 :(得分:3)
public GenericClass(String argument)
问题在于,编译器应该如何知道String
是T
?参数与泛型类型参数之间没有链接,也无法指定一个。您可以使用
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;
}