Java形式类型参数定义(泛型)
我想定义一个泛型类型,它的实际类型参数只能是Java形式类型参数定义(泛型),java,generics,Java,Generics,我想定义一个泛型类型,它的实际类型参数只能是 数值基本包装类之一(Long,Integer,Float,Double) String 我可以用这样的定义满足第一个要求 public final class MyClass<T extends Number> { // Implementation omitted } 公共最终类MyClass{ //省略实现 } 但我想不出如何满足他们两个。我怀疑这实际上是不可能的,因为AFAIK在定义正式类型参数时无法指定“或”语义,尽管
Long
,Integer
,Float
,Double
)String
public final class MyClass<T extends Number> {
// Implementation omitted
}
公共最终类MyClass{
//省略实现
}
但我想不出如何满足他们两个。我怀疑这实际上是不可能的,因为AFAIK在定义正式类型参数时无法指定“或”语义,尽管您可以使用以下定义指定“和”语义
public final class MyClass<T extends Runnable & Serializable > {
// Implementation omitted
}
公共最终类MyClass{
//省略实现
}
干杯,
别问这个有趣的问题,我有点困惑。然而,这显然是不可能的。我尝试了几种不同的方法,没有一种真正有效。Java泛型不支持联合类型(此参数可以是A或B) 在一些人可能感兴趣的相关注释中,如果您想要强制执行多个限制,它确实支持多个边界。下面是Java中提到的JDK的一个示例:
publicstatic虽然泛型在这里不起作用,但是带有Number
和String
派生类型的基类型将起作用。由于泛型类型无论如何都会被擦除为对象
,因此您在其中放置的任何功能都可以放在抽象基类中。您可能只需要子类上的特定于类型的访问器就可以获得该值
另外,请注意编号
类。它不限于装箱基本类型,因为任何人都可以对其进行扩展,例如,biginger
您可以对所有支持的类型使用工厂方法,并使构造函数私有/受保护。无论如何,您都必须修复构造函数中的泛型类型,这样它才有意义,所以您可能可以这样编写它:
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{
公共静态MyClass newInstance(int i){
返回新的MyClass(i);
}
公共静态MyClass newInstance(字符串s){
返回新的MyClass;
}
//更多工厂方法。。。
受保护的MyClass(T obj){
//...
}
}
或者,如果您不需要构造函数参数,请执行以下操作:
公共期末班MyClass{
公共静态MyClass newIntegerInstance(){
返回新的MyClass();
}
//...
}
正如erickson所说,通用实现无论如何只能依赖对象,因此唯一的限制是,除了原语和字符串之外,您还可以为其他类型创建其他实现。也许您可以执行以下操作:
将MyClass
设为包默认类,对其他组件不可见,或者至少只使用包默认的ctors,以便它不能在包外部扩展或实例化
在MyClass
的包中创建两个公共类:
MyNumericClass扩展了MyClass
MyStringClass扩展了MyClass
这样,MyClass的所有子类都将被限制为那些用数字子类或字符串参数化的子类。类型擦除将把它放回object(如果它存在的话)。这不是一个坏例子吗(我看到它来自SUN,不是你的)@马库斯不,这是个不错的例子。不一样。如果没有“扩展对象”,则签名类型是可比较的(不是从对象继承的),而不是所需的对象。
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) {
//...
}
}
MyNumericClass<T extends Number> extends MyClass<T>
MyStringClass extends MyClass<String>