限制泛型类型

时间:2014-05-30 15:13:41

标签: java

在Java中是否可以将泛型类型<T>限制为仅限于某些类型:

  • Boolean
  • Integer
  • Long
  • Float
  • String

编辑:我的问题是将泛型类型<T>限制为不具有常见直接超类的不同类类型。


编辑:我最终使用了Reimeus提出的方案:

public class Data<T> {

    private T value;

    private Data(T value) {
        this.set(value);
    }

    public static Data<Integer> newInstance(Integer value) {
        return new Data<Integer>(value);
    }

    public static Data<Float> newInstance(Float value) {
        return new Data<Float>(value);
    }

    public static Data<String> newInstance(String value) {
        return new Data<String>(value);
    }

    public T get() {
        return this.value;
    }

    public void set(T value) {
        this.value = value;
    }
}

Data<Integer> data = Data.newInstance(10);

修改:另一种方法:

public class Data<T> {

    private T value;

    private Data(T value) {
        this.set(value);
    }

    @SuppressWarnings("unchecked")
    public Data(Integer value) {
        this((T) value);
    }

    @SuppressWarnings("unchecked")
    public Data(Float value) {
        this((T) value);
    }

    @SuppressWarnings("unchecked")
    public Data(String value) {
        this((T) value);
    }

    public T get() {
        return this.value;
    }

    public void set(T value) {
        this.value = value;
    }
}

但我有一个问题:

如果错误地将data实例声明为:

Data<Integer> data = new Data<Integer>(3.6f); // Float instead of Integer

没有类强制转换异常,data.get()返回3.6

我不明白为什么......

所以,第一个解决方案似乎更好。

3 个答案:

答案 0 :(得分:3)

您可以通过多态来限制它,例如:

<T super X> //Matches X and all superclasses of X

<T extends X> //Matches X and all subclasses of X

但是,您不能将其限制为本质上不相关的任意类型列表。

答案 1 :(得分:2)

它不可能,因为它们都来自不同的父类(一些直接来自Object,一些直接来自Number)。虽然您可以将泛型类型仅限于

Integer
Long
Float

以及Number的其他子类<T extends Number>

PS:对于您的要求,<T extends Serializable>会起作用,但这也会接受实施Serializable的所有其他类(感谢@Jeroen Vannevel评论)

答案 2 :(得分:2)

不可能使用单个声明的类型<T>,但您可以定义一个包装类,为所需类型提供工厂方法

public class Restricted<T> {

    private T value;

    public Restricted(T value) {
        this.value = value;
    }

    public static Restricted<Boolean> getBoolean(Boolean value) {
        return new Restricted<Boolean>(value);
    }

    public static Restricted<Integer> getInteger(Integer value) {
        return new Restricted<Integer>(value);
    }

    public static Restricted<Double> getLong(Double value) {
        return new Restricted<Double>(value);
    }

    // remaining methods omitted
}