java在switchcase语句中使用枚举的序数值
对于我的项目,我使用的是枚举,我需要实现switch case语句,其中检查特定枚举值的序号,如下所示:
switch ( variable )
{
case MyEnum.A.ordinal():
return true;
case MyEnum.B.ordinal():
return true;
default:
return false;
}
注意:返回值只是一个示例
不幸的是,Eclipse(我使用的是1.6 JDK)给出了我的编译错误“案例” 表达式必须是常量表达式”。我应该做什么?除了静态查找表,还有其他方法吗,这里描述:Convert from enum ordinal to enum type
# 1 楼答案
答案的目标是@RIA对常量vs方法枚举和性能原因的评论,它没有直接回答OP问题,所以我认为它可以被视为噪声。 然而,我相信了解内部工作原理是很重要的
我将基准测试从他的示例中去掉,并对其进行了改进,以消除占执行时间90%以上的垃圾收集和字符串创建。增加了预热阶段,以确保hotspot实际编译方法
还有一些,基准测试实际上是调用站点测试。调用站点的优化对于1、2和更多都有很大不同。调用站点是对抽象(或刚刚重写)方法的调用
以下是6个枚举常量的测试:
代码是用/
-server -XX:+PrintCompilation
选项运行的。 当然,差别并不大。然而,这不是一个有趣的问题。但是,如果使用2个枚举常量测试该版本,结果可能会显著不同。对于2个调用站点,编译器通过内联相关方法生成代码。在上面的测试中,这将删除对booleanValue的整个调用,甚至可以让您在O(1)中执行测试然而,最有趣的是,当编译器开始使用内联缓存时,从2个枚举常量变为3个枚举常量,然后是常量,然后一切都变了
底线是:正确的基准测试确实很难,需要了解JIT是如何编译的,何时GC可能会出现问题(要么删除它,要么接受它),等等。
链接:
# 2 楼答案
如果你在某处有一个序列化的序数,就是这样做的。不过,保持枚举的通常方法是按其名称,而不是按顺序。此外,除非尝试实现EnumMap/Set之类的功能,否则在正常情况下不应使用ordinal。当然,枚举可以只是C类的一个端口,处理不可避免的int,需要对枚举对象进行转换
只需使用
Enum.values()
获得一个按ordinal()
排序的数组,因为数组每次都被克隆,所以保持一个ref是可以的注意到你只需要对和错,这是一种固定的行为。你可以使用java。util。枚举集或简单的
long
,如果感觉勇敢(且枚举常量不超过64个)。例如:# 3 楼答案
只需使用枚举常量:
假设:
但是要小心
NullPointerException
(如果variable
是null
)# 4 楼答案
首先,你不应该太依赖序数。如果可能的话,将变量设置为
String
(并使用Enum.valueOf(string)
转换为enum
),或者最多设置为enum
如果你真的不能,那就用
enum.values()[ordinal]
。然后使用交换机中的枚举# 5 楼答案
你想要的可能是: 如果在枚举本身的方法中需要开关:
在另一个班级:
但是,如果添加另一个enum,很容易忘记更新switch语句,因此更好的选择是在enum本身中放置类似的方法,并使用特定于常量的方法实现:
这样,如果您添加了一个新的枚举值,编译器会提醒您声明getBooleanValue方法,您只需在需要的地方使用
A.getBooleanValue();
正如评论中指出的,另一种选择是:
这是一个偏好问题,具体情况会有所不同。如果只是为每个枚举返回一个值,那么构造函数的版本是合理的,但我发现它的可读性较差。通过测试可以看出,对这种性能更好的担忧是毫无根据的:
# 6 楼答案
更好的解决方案是这样的:
枚举:
实施:
戴夫,文伯康(manpakhong@hotmail.com)