class A <T> {
private T field;
}
我知道我可以使用&lt;强制类型参数为某种有界类型。 ... extends ...&gt;,但是我如何强制类型参数T只能是String,Integer,SomeClassB,SomeEnumC而不能用其他任何东西进行参数化?
A<SomeClassB> a = new A<SomeClassB>();
合法。
A<SomeClassX> a = new A<SomeClassX>();
是非法的。
我已经尝试使用
测试这些类型T instanceof SomeEnumC
在A类的构造函数中,但它非常混乱。
答案 0 :(得分:2)
注意:我同意@ Jeffrey上面的评论,这似乎没有多大意义,因为它似乎不会获得任何有用的类型信息通过这种限制。我真的很想知道你的用例是什么。
您不能将T
可接受的泛型类型限制为不相关类的列表,例如您的示例。您只能使用super
或extends
来限制泛型类型,这意味着它们必须是某些给定类型的超类型或子类型。
但是,由于您希望T
允许的课程数量有限,因此您应该能够枚举所有课程。这就是我的想法:
public class A<T> {
/**
* Private constructor means only nested classes
* can extend this class. We use this to limit the
* types that can be used for T.
*/
private A() { }
/** Integer version of A */
public static class IntA extends A<Integer> { }
/** String version of A */
public static class StringA extends A<String> { }
}
现在,您可以使用static import导入所需的A<T>
嵌套版本,或者所有这些版本如下:import static A.*;
答案 1 :(得分:1)
我假设您要将A类导出为API的一部分,这就是您希望限制可以作为泛型类型参数传递的类型的原因。
如果要限制类A的类型列表是已知的(并且数量相当小),那么解决方法是定义一个包 - 私有接口(这将阻止包外的类实现接口):
interface A <T> {
T field;
}
然后,您可以简单地为您希望允许的类型编写具体的类。因为没有其他人可以实现你的界面,所以没有人可能根据你不打算允许的类型编写一个类。
答案 2 :(得分:0)
你不能在编译时限制它,但稍微调整就可以在运行时强制执行它:
class A <T> {
private T field;
public A(Class<T> c) {
if (c != String.class | c != Integer.class | c != SomeClassB.class | c != SomeClassC.class)
throw new IllegalArgumentException();
}
}
答案 3 :(得分:0)
我认为你的设计可能存在缺陷,更好的设计可以避免需要这样做。但是,如果您真的想要使用此路由,请使用私有构造函数和工厂方法:
public class A<T> {
private T field ;
private A(T t) {
this.field = t ;
}
public static A<String> getInstance(String s) {
return new A<String>(s);
}
public static A<Integer> getInstance(Integer i) {
return new A<Integer>(i);
}
// etc....
// regular instance methods...
public void doStufF() {
if (field instanceof Integer) { /* ... */ }
else if (field instanceof String) { /* ... */ }
}
}
每当你看到丑陋的if / else开启类型时,你应该考虑“丰富的枚举......”,就像在scottb的答案之后的讨论一样。