2008-12-11 67 views
8

我想定义泛型类型,其实际的类型参数只能是Java的形式类型参数定义(仿制药)

  1. 一个数字基本类型的包装类(LongIntegerFloatDouble
  2. String

我能满足这样的

定义的第一要求
public final class MyClass<T extends Number> { 
    // Implementation omitted 
} 

但我无法弄清楚如何满足他们两个。我怀疑这是不实际的,因为据我所知没有办法来指定“或”定义形式类型参数时语义,虽然你可以使用一个定义如

public final class MyClass<T extends Runnable & Serializable > { 
    // Implementation omitted 
} 

干杯, 唐注明“和”语义

+0

如果存在,类型擦除会将其放回对象。 – Loki 2008-12-11 20:48:50

回答

0

有趣的问题,它让我有些不解。但显然这是不可能的。我尝试了几种不同的黑客,没有任何工作。

11

Java泛型不支持联合类型(此参数可以是A或B)。

如果您想要强制执行多个限制,可能会对某些相关注释感兴趣,但它支持多个边界。下面是从JDK在Java generics tutorial提到一个例子:

public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) 
+1

这不是一个坏例子(我看它来自SUN,不是你的)? >与>相同,是不是? 并不意味着什么。 – Markus 2008-12-12 18:44:06

2

虽然仿制药将在这里工作,基本类型与派生类型NumberString意志。因为无论如何,泛型类型已经被擦除到Object,所以你可能会在抽象基类中放置任何功能。您可能只需要子类上的特定于类型的访问器即可获取该值。

另外,请注意Number类。它不限于对原始类型进行装箱,因为任何人都可以对其进行扩展,例如BigInteger

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) { 
     //... 
    } 
} 

或者,如果你不希望构造函数的参数,是这样的: 公共决赛class MyClass public static MyClass newIntegerInstance(){ return new MyClass(); } // ... }

正如埃里克森所说,共同实现只能在对象靠无论如何,所以唯一的限制是,你可以创建其他实现对其他类型除了原始和字符串。

0

也许你能做些什么如下:

  1. MyClass<T>包,默认类,不可见的其他组件,或至少只能在包的默认构建函数,所以它不能扩展或外部的实例包。
  2. 在包的MyClass<T>创建两个公共类:
MyNumericClass<T extends Number> extends MyClass<T> 
MyStringClass extends MyClass<String> 

这样MyClass的所有子类将被限制在那些具有数子或字符串参数化。