将此函数转换为使用泛型

时间:2012-02-02 03:11:03

标签: java generics

我有一个函数,我试图使用泛型转换,到目前为止我有:

public static <T extends Enum<T> & SomeInterface> EnumSet<T> convertToES(long val) {
  EnumSet<T> es = EnumSet.noneOf(T.class);

  for(T t : values()) {
      if(t.getSomeProperty() > 0)
        es.add(t);
  }


  return es;
}

SomeInterface具有单个属性getSomeProperty。

T.class不起作用,而且值()似乎也不起作用。

以前我曾经:

public static EnumSet<SomeType> convertToES(long val) {
        EnumSet<SomeType> es = EnumSet.noneOf(SomeType.class);

        for (SomeType p : values()) {
            if (p.getSomeThing())) > 0) {
                es.add(p);
            }
        }

        return es;
    }

有没有办法让这项工作成功,或者这是不可能的?

3 个答案:

答案 0 :(得分:3)

这是因为Java通过 erasure 实现了泛型,因此T在运行时不存在。 Java中的泛型只是一种语言工具,可以帮助您避免在编译时发生太多错误。

解决方案是要求调用方法的人将类本身作为一个真正的参数:

public static <T extends Enum<T> & SomeInterface> EnumSet<T> convertToES(
    long val,
    Class<T> tClass) 
{
    EnumSet<T> es = EnumSet.noneOf(tClass);

values()而言,该方法存在于枚举类本身,因此如果您已将代码移出该类,则需要以另一种方式获取值:

    for(T t : tClass.getEnumConstants()) {
        ....

答案 1 :(得分:0)

T.class没有工作,因为T不是一个类。 你可能需要内省。我建议采取以下措施:

public static <T extends Enum<T> & SomeInterface> EnumSet<T> convertToES(Class<T> clazz, long val) {

    EnumSet<T> es = EnumSet.noneOf(clazz);

    for(T t : clazz.getEnumConstants()) {
        if(t.getSomeProperty() > 0)
          es.add(t);
    }
    return es;
  }

答案 2 :(得分:0)

该方法不知道您想要哪个enumset - 它无法知道。我建议把它传递进去:

public static <T extends Enum<T> & SomeInterface> //
        EnumSet<T> convertToES(Class<T> tClass, long val) {
    EnumSet<T> set = EnumSet.noneOf(tClass);
    for (T t : EnumSet.allOf(tClass)) {
        if (t.getSomeProperty() == val) {
            set.add(t);
        }
    }
    return set;
}

这样称呼:

EnumSet<Foo> x = convertToES(Foo.class, 3);

甚至

for(Foo suitableFoo: convertToES(Foo.class, 5)) {
    print(suitableFoo + " has a property of 5!");
}