假设我有一个通用类Foo
它可以保存类型的对象T
。此外,假设我only希望能够使用两种类型之一的对象实例化该类。最后,假设这两种类型的最低公共上限是一种比我想要允许的两种类型拥有更多子类的类型,因此我不能简单地为类型参数指定一个上限(如class Foo<T extends Something>
),因为这样我将允许使用除我期望的两种类型以外的其他类型来实例化该类。
为了便于说明,假设我想要Foo
持有only要么是String
or an Integer
。最低公共上限是Object
,因此指定上限并不能解决问题。
当然,我可以做一些类似的事情
class Foo<T> {
private T obj;
public Foo(T obj) throws IllegalArgumentException {
if (!(obj instanceof String || obj instanceof Integer)) {
throw new IllegalArgumentException("...");
}
this.obj = obj;
}
}
但是,在这种情况下,我仍然可以使用以下命令调用构造函数any目的;如果我尝试用既不是String
nor an Integer
,我会得到一个例外runtime.
我想做得更好。我希望编译器静态推断(即,在编译时间)我只能用以下对象实例化此类String
or Integer
.
我在想类似的东西可能会起作用:
class Foo<T> {
private T obj;
public Foo(String s) {
this((T) s);
}
public Foo(Integer i) {
this((T) i);
}
private Foo(T obj) {
this.obj = obj;
}
}
这可行,但看起来真的非常奇怪。编译器会警告(可以理解)未经检查的强制转换。当然,我可以抑制这些警告,但我觉得这不是正确的方法。另外,看起来编译器实际上不能infer方式T
。我惊讶地发现,后面的类定义Foo
,我可以这样做,例如:
Foo<Character> foo = new Foo<>("hello");
当然,类型参数应该是String
在这里,不Character
。但编译器让我摆脱了上面的分配。
- 有没有办法实现我想要的,如果是的话,如何实现?
- 附带问题:为什么编译器让我逃脱对类型对象的赋值
Foo<Character>
上面甚至没有一个warning(当使用后一个类定义时Foo
)? :)