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>