关注我,可了解更多有趣的面试相关问题。
本篇收录于《计算机核心知识串讲》
写在之前
今天 review
代码,突然看到了一个这样一行代码,大概的作用是比较两个活动类型枚举是否相等。
ActivityTypeEnum.COUPON_ACTIVITY.getType() == activity.getType();
这行代码给我看得一愣一愣的,为什么不直接比较枚举,而是获取 type
,再进行比较呢?
按照我的理解枚举不是可以直接用 == 比较吗?
先说结论,我这句话是对的。如果你对我这句话不知道为什么欢迎继续往下看。
其中ActivityTypeEnum
定义如下:
public enum ActivityTypeEnum {
COUPON_ACTIVITY (1, "优惠券活动"),
SECKILL_ACTIVITY(2, "秒杀活动");
private Integer type;
private String desc;
ActivityTypeEnum (int type, String desc) {
this.type = type;
this.desc = desc;
}
public Integer getType() {
return type;
}
}
源码一窥
能不能用 ==
或者 equals
比较,其实就是看两个对象是不是同一个对象,进一步说,其实就是看枚举类的构造方法是如何定义的。
关于equals 和 == 区别可以查看 面试中equals()、==、HashCode()再分不清你打我
看看源码的构造方法描述,原文如下:
/**
* Sole constructor. Programmers cannot invoke this constructor.
* It is for use by code emitted by the compiler in response to
* enum type declarations.
*
* @param name - The name of this enum constant, which is the identifier
* used to declare it.
* @param ordinal - The ordinal of this enumeration constant (its position
* in the enum declaration, where the initial constant is assigned
* an ordinal of zero).
*/
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
我大概翻译一下这句话:jdk
说这个是唯一的构造器,并且程序员是不可以调用的哦,只能是编译器在用户声明枚举类型的时候调用。
这说明什么?
说明每个枚举类型都是不可变的(没有 public
的构造方法,用户根本没有办法修改)。所有枚举常量都通过静态代码块来进行初始化,即在类加载期间就初始化,同一个类型使用的是同一个静态地址块。
比如
ActivityTypeEnum activity1 = GameEnum.COUPON_ACTIVITY;
ActivityTypeEnum activity2 = GameEnum.COUPON_ACTIVITY;
activity1
和 activity2
指向同一个 GameEnum.COUPON_ACTIVITY
,其内存地址又是同一个。
所以以上代码可以改成这样的:ActivityTypeEnum.COUPON_ACTIVITY == activity;
既然 == 都可以比较了,那能不能用 equals()
比较呢?
答案是可以的。
我们可以大概看一下源码:
public final boolean equals(Object other) {
return this==other;
}
发现没?enum
的 equals()
,其内部实现就是调用的 == ,并且该方法默认是final的(即不可以被改变)
总结
我们简单总结一下,比较两个枚举类型,可以直接用 ==
或者 equals()
直接比较。




