为何Java枚举常量可链式调用无报错且输出最后一个值?
为什么枚举常量可以链式调用且输出最后一个?
这其实是Java里关于静态成员访问规则的一个小细节,咱们一步步拆解清楚:
1. 你的枚举类本质是什么?
先看你定义的Currency枚举:
public enum Currency { PENNY(1), NICKLE(5), DIME(10), QUARTER(25); private int value; private Currency(int value) { this.value = value; } };
这里的每个枚举常量(PENNY、NICKLE、DIME、QUARTER)都是Currency类的静态final实例——它们既是Currency类型的对象,同时也是属于Currency类的静态成员。
2. 链式调用的实际逻辑
当你写Currency.NICKLE.DIME.PENNY.QUARTER时,Java的执行逻辑是这样的:
- 首先
Currency.NICKLE:获取到NICKLE这个枚举实例(它是Currency类型的对象) - 接着
.DIME:通过NICKLE实例访问DIME——但DIME是Currency类的静态成员,Java允许通过类的实例来访问静态成员(虽然这是不推荐的编码习惯) - 后续的
.PENNY、.QUARTER都是重复同样的逻辑:每次都是通过前一个枚举实例,访问下一个属于Currency类的静态枚举常量
所以整个链式调用最终等价于Currency.QUARTER,自然打印的就是链式里最后一个枚举常量。同理,Currency.PENNY.QUARTER等价于Currency.QUARTER。
3. 额外验证:区分静态和非静态成员
如果在你的枚举类里加一个非静态字段:
public enum Currency { PENNY(1), NICKLE(5), DIME(10), QUARTER(25); private int value; public String instanceField = "I'm an instance field"; // 非静态字段 private Currency(int value) { this.value = value; } };
这时候调用Currency.NICKLE.instanceField会返回NICKLE实例的instanceField值;但调用Currency.NICKLE.PENNY依然是访问静态的PENNY常量,和NICKLE实例本身完全无关。
4. 小提示:这种写法不规范
虽然Java允许这么写,但这是不符合编码规范的,大多数IDE会给你警告(比如"Static member accessed via instance reference")。静态成员属于类,应该直接用类名访问(比如Currency.QUARTER),而不是通过实例链式调用。
内容的提问来源于stack exchange,提问作者Nicky
相关产品推荐
相关产品推荐

