我想定义一个泛型类型,其实际类型参数只能是
Long
,Integer
,Float
,Double
)String
我可以通过像这样的定义来满足第一个要求
public final class MyClass<T extends Number> {
// Implementation omitted
}
但我无法弄清楚如何满足他们两个。我怀疑这实际上是不可能的,因为AFAIK在定义形式类型参数时无法指定“或”语义,尽管您可以使用诸如
之类的定义来指定“和”语义public final class MyClass<T extends Runnable & Serializable > {
// Implementation omitted
}
干杯, 唐
答案 0 :(得分:11)
Java泛型不支持联合类型(此参数可以是A OR B)。
在一些可能感兴趣的相关注释中,如果要强制执行多个限制,它确实支持多个边界。以下是Java generics tutorial中提到的JDK的一个示例:
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
答案 1 :(得分:4)
您可以对所有受支持的类型使用工厂方法,并使构造函数为private / protected。你必须在构造函数中修改泛型类型,以便它有意义,所以你可能会像这样编码:
public final class MyClass<T> {
public static MyClass<Integer> newInstance(int i) {
return new MyClass<Integer>(i);
}
public static MyClass<String> newInstance(String s) {
return new MyClass<String>(s);
}
//More factory methods...
protected MyClass(T obj) {
//...
}
}
或者如果你不想要构造函数参数,就像这样: 公共最终类MyClass { public static MyClass newIntegerInstance(){ 返回新的MyClass(); } // ... }
正如erickson所说,通用实现无论如何都只能依赖于Object,所以唯一的限制是,除了原语和String之外,你还可以为其他类型创建其他实现。
答案 2 :(得分:2)
虽然泛型在此处不起作用,但Number
和String
的派生类型的基本类型将会生效。由于泛型类型无论如何都会被删除到Object
,因此您在其中放置的任何功能都可以放在抽象基类中。您可能只需要子类上特定于类型的访问器来获取值。
另外,请注意Number
课程。它并不局限于装箱原始类型,因为任何人都可以扩展它 - 例如,BigInteger
。
答案 3 :(得分:0)
有趣的问题,它让我感到困惑。但显然这是不可能的。我尝试了几种不同的黑客,没有一种真正起作用。
答案 4 :(得分:0)
也许你可以做以下事情:
MyClass<T>
成为一个包默认类,对其他组件不可见,或者至少只使用包默认的ctors,这样它就无法在包外扩展或实例化。MyClass<T>
:MyNumericClass<T extends Number> extends MyClass<T> MyStringClass extends MyClass<String>
这样,MyClass的所有子类都将限于那些使用Number子类或String进行参数化的子类。