Java枚举构造器无法调用values()时如何为最后一个枚举设置不同变量值
问题原因
原写法不生效的根本原因是:枚举构造器执行阶段,所有枚举实例都还没完成初始化,此时既不允许调用values()方法,就算绕过语法限制调用,也拿不到完整的枚举实例数组,根本无法判断当前实例是否为最后一个。
可行实现方案
方案1:静态代码块后置赋值(推荐)
所有枚举实例初始化完成后,类的静态代码块才会执行,此时调用values()可以拿到完整的实例列表,直接修改最后一个实例的成员变量即可。这个方案不需要硬编码实例位置,后续增删枚举实例也不需要调整这部分逻辑,适配性最好。
private enum Thing { THING0(0), THING1(1), THING2(2); int index; String s; Thing(int index) { this.index = index; // 构造器先给所有实例赋默认值 this.s = "a"; } static { Thing[] allInstances = values(); // 单独给最后一个实例设置差异化取值 allInstances[allInstances.length - 1].s = "b"; } }
方案2:显式给最后一个实例传参
如果你的枚举实例顺序长期不会调整,可以直接在声明最后一个实例的时候传入差异化的参数值,逻辑最直白,没有额外的后置处理逻辑:
private enum Thing { THING0(0, "a"), THING1(1, "a"), THING2(2, "b"); // 最后一个实例直接传入差异化取值 int index; String s; Thing(int index, String s) { this.index = index; this.s = s; } }
这个方案的缺点是可维护性差,后续如果调整枚举实例顺序、增删实例,很容易忘记同步修改参数,导致差异化值配错位置。
注意避坑
- 不要尝试在构造器中通过
ordinal()方法判断是否为最后一个实例:一方面构造器执行阶段无法获取枚举实例总数量,判断逻辑根本不成立;另一方面ordinal()是JVM给枚举实例分配的内置顺序值,官方本身就不推荐在业务逻辑中依赖这个值做判断,只要调整实例声明顺序就会触发逻辑错误。
内容的提问来源于stack exchange,提问作者H.v.M.
相关产品推荐
相关产品推荐

