Java选择性泛型

时间:2013-11-09 22:59:00

标签: java generics types parameters

class A <T> {

    private T field;
}

我知道我可以使用&lt;强制类型参数为某种有界类型。 ... extends ...&gt;,但是我如何强制类型参数T只能是String,Integer,SomeClassB,SomeEnumC而不能用其他任何东西进行参数化?

A<SomeClassB> a = new A<SomeClassB>();

合法。

A<SomeClassX> a = new A<SomeClassX>();

是非法的。

我已经尝试使用

测试这些类型
T instanceof SomeEnumC

在A类的构造函数中,但它非常混乱。

4 个答案:

答案 0 :(得分:2)

注意:我同意@ Jeffrey上面的评论,这似乎没有多大意义,因为它似乎不会获得任何有用的类型信息通过这种限制。我真的很想知道你的用例是什么。


您不能将T可接受的泛型类型限制为不相关类的列表,例如您的示例。您只能使用superextends来限制泛型类型,这意味着它们必须是某些给定类型的超类型或子类型。

但是,由于您希望T允许的课程数量有限,因此您应该能够枚举所有课程。这就是我的想法:

public class A<T> {

  /**
   * Private constructor means only nested classes
   * can extend this class. We use this to limit the
   * types that can be used for T.
   */
  private A() { }

  /** Integer version of A */
  public static class IntA extends A<Integer> { }

  /** String version of A */
  public static class StringA extends A<String> { }

}

现在,您可以使用static import导入所需的A<T>嵌套版本,或者所有这些版本如下:import static A.*;

答案 1 :(得分:1)

我假设您要将A类导出为API的一部分,这就是您希望限制可以作为泛型类型参数传递的类型的原因。

如果要限制类A的类型列表是已知的(并且数量相当小),那么解决方法是定义一个包 - 私有接口(这将阻止包外的类实现接口):

interface A <T> {
    T field;
}

然后,您可以简单地为您希望允许的类型编写具体的类。因为没有其他人可以实现你的界面,所以没有人可能根据你不打算允许的类型编写一个类。

答案 2 :(得分:0)

你不能在编译时限制它,但稍微调整就可以在运行时强制执行它:

class A <T> {
    private T field;
    public A(Class<T> c) {
        if (c != String.class | c != Integer.class | c != SomeClassB.class | c != SomeClassC.class)
            throw new IllegalArgumentException();
    }
}

答案 3 :(得分:0)

我认为你的设计可能存在缺陷,更好的设计可以避免需要这样做。但是,如果您真的想要使用此路由,请使用私有构造函数和工厂方法:

public class A<T> {
    private T field ;

    private A(T t) {
        this.field = t ;
    }

    public static A<String> getInstance(String s) {
        return new A<String>(s);
    }

    public static A<Integer> getInstance(Integer i) {
        return new A<Integer>(i);
    }

    // etc....

    // regular instance methods...

    public void doStufF() {
        if (field instanceof Integer) { /* ... */ }
        else if (field instanceof String) { /* ... */ }
    }
}

每当你看到丑陋的if / else开启类型时,你应该考虑“丰富的枚举......”,就像在scottb的答案之后的讨论一样。