我有枚举类型ReportTypeEnum,在我所有的类的方法之间传递,但我需要在URL上传递这个,所以我使用序数方法来获得int值。在我的另一个JSP页面中获得它之后,我需要将它转换回ReportTypeEnum,以便我可以继续传递它。
如何将序数转换为ReportTypeEnum?
使用Java 6 SE。
我有枚举类型ReportTypeEnum,在我所有的类的方法之间传递,但我需要在URL上传递这个,所以我使用序数方法来获得int值。在我的另一个JSP页面中获得它之后,我需要将它转换回ReportTypeEnum,以便我可以继续传递它。
如何将序数转换为ReportTypeEnum?
使用Java 6 SE。
当前回答
这就是我用的。我并不是说它远不如上面那些简单的解决方案“有效”。当在上面的解决方案中使用无效序数值时,它所做的是提供比"ArrayIndexOutOfBounds"更清晰的异常消息。
它利用了EnumSet javadoc指定迭代器以自然顺序返回元素的事实。如果不正确,就有一个断言。
JUnit4测试演示了如何使用它。
/**
* convert ordinal to Enum
* @param clzz may not be null
* @param ordinal
* @return e with e.ordinal( ) == ordinal
* @throws IllegalArgumentException if ordinal out of range
*/
public static <E extends Enum<E> > E lookupEnum(Class<E> clzz, int ordinal) {
EnumSet<E> set = EnumSet.allOf(clzz);
if (ordinal < set.size()) {
Iterator<E> iter = set.iterator();
for (int i = 0; i < ordinal; i++) {
iter.next();
}
E rval = iter.next();
assert(rval.ordinal() == ordinal);
return rval;
}
throw new IllegalArgumentException("Invalid value " + ordinal + " for " + clzz.getName( ) + ", must be < " + set.size());
}
@Test
public void lookupTest( ) {
java.util.concurrent.TimeUnit tu = lookupEnum(TimeUnit.class, 3);
System.out.println(tu);
}
其他回答
要将一个序数转换为它的枚举表示,你可能想这样做:
ReportTypeEnum value = ReportTypeEnum.values()[ordinal];
请注意数组的边界。
注意,每次调用values()都会返回一个新克隆的数组,这可能会对性能产生负面影响。如果经常调用数组,可能需要缓存数组。
关于如何缓存值的代码示例()。
这个回答经过编辑,包含了评论中的反馈
每个枚举都有name(),它给出一个包含枚举成员名称的字符串。
给定一个花色{红心,黑桃,梅花,方块},Suit.Heart.name()将给出红心。
每个枚举都有一个valueOf()方法,该方法接受一个枚举类型和一个字符串,以执行相反的操作:
枚举. valueof (Suit.class, "Heart")返回Suit.Heart。
我真搞不懂为什么会有人用序数。它可能会快几纳秒,但如果枚举成员发生变化,则不安全,因为另一个开发人员可能不知道某些代码依赖于序数值(特别是在问题中引用的JSP页面中,网络和数据库开销完全占据了时间,而不是使用整数而不是字符串)。
通过这种方式,您可以不依赖于编译时泛型解析(因此您可以随时创建枚举类实例,即使是使用class . formame创建的类型)
public Object getInstance(Class enumClazz, int ordinal) throws Exception {
Object[] allEnums = enumClazz.getDeclaredMethod("values", Object[].class).invoke(null, null);
return allEnums[ordinal];
}
public enum Suit implements java.io.Serializable, Comparable<Suit>{
spades, hearts, diamonds, clubs;
private static final Suit [] lookup = Suit.values();
public Suit fromOrdinal(int ordinal) {
if(ordinal< 1 || ordinal> 3) return null;
return lookup[value-1];
}
}
测试类
public class MainTest {
public static void main(String[] args) {
Suit d3 = Suit.diamonds;
Suit d3Test = Suit.fromOrdinal(2);
if(d3.equals(d3Test)){
System.out.println("Susses");
}else System.out.println("Fails");
}
}
我很感激你与我们分享,如果你有一个更有效的代码,我的enum是巨大的,不断调用数千次。
如果我要大量使用values():
enum Suit {
Hearts, Diamonds, Spades, Clubs;
public static final Suit values[] = values();
}
同时wherever.java:
Suit suit = Suit.values[ordinal];
如果你想要数组是私有的,请自便:
private static final Suit values[] = values();
public static Suit get(int ordinal) { return values[ordinal]; }
...
Suit suit = Suit.get(ordinal);
注意数组的边界。