Java:枚举类型的通用方法

31

帮我理解泛型。假设我有两个枚举作为内部类,像这样:

public class FoodConstants {
    public static enum Vegetable {
        POTATO,BROCCOLI,SQUASH,CARROT;
    }

    public static enum Fruit {
        APPLE,MANGO,BANANA,GUAVA;
    }
}

我希望将两个枚举类都实现同一个接口并且不用重复实现相同的方法,所以我想在外部类中编写一个方法,类似于:

public <e> String getEnumString<Enum<?> e, String s) {
    for(Enum en: e.values()) {
        if(en.name().equalsIgnoreCase(s)) {
            return s;
        }
    }
    return null;
}

然而,这种方法无法编译。我的目的是找出一个字符串值是否为任何枚举类型的名称,无论它是蔬菜、水果或其他东西。

不管这是否是一个多余的方法,我试图(重新)编写的方法有什么问题?

public class FoodConstants {
    public static enum Vegetable {
        POTATO,BROCCOLI,SQUASH,CARROT;
    }

    public static enum Fruit {
        APPLE,MANGO,BANANA,GUAVA;
    }

    public <e> String getEnumString<Enum<?> e, String s) {
        for(Enum en: e.values()) {
            if(en.name().equalsIgnoreCase(s)) {
                return s;
            }
        }
        return null;
    }
} //end of code
1个回答

67
public static <E extends Enum<E>>
String getEnumString(Class<E> clazz, String s){
  for(E en : EnumSet.allOf(clazz)){
    if(en.name().equalsIgnoreCase(s)){
      return en.name();
    }
  }
  return null;
}

以下是一些问题:

  1. 它接受枚举实例而不是表示您想要使用的枚举的类。
  2. 类型参数未被使用。
  3. 它返回输入而不是实例名称。也许返回实例会更有用--一个不区分大小写的版本Enum.valueOf(String)
  4. 它在实例上调用静态方法以便您可以进行迭代。 EnumSet 为您完成所有反射工作。

6
clazz.getEnumConstants()可以替代EnumSet.allOf(clazz)。鉴于EnumSet.allOf可能基于这个实现,clazz.getEnumConstants()可能略微更有效率,但也有可能不是。 - Sebastian Redl
@SebastianRedl,奇怪。我以为在1.5中不可用,但显然它是可用的。 - Mike Samuel
8
@SebastianRedl说,实际上EnumSet.allOf().getEnumConstants()更有效率,因为.getEnumConstants()必须复制常量的内部数组(因为它返回一个数组,并且没有办法防止数组被修改),而EnumSet可以使用内部实现细节直接迭代内部数组。 - newacct
使用这个签名会导致编译时出现“坏的类文件”和“未声明类型变量:T”的错误。 - Joe Cabezas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接