Java枚举类学习
前言
枚举类对我而言一直是非常神秘的特性,最近学习thinking in Java,将枚举类的特性总结下,只为了加深印象。
枚举类
初探
枚举类的ordinal()表示序号,name()表示名称。
比较枚举类的大小可以放心使用==或equals to。
valueOf可以在枚举变量中寻找匹配的字符串并返回改变量。
enum Sports {
BASKETBALL,
SOCCOR,
PINGPONG
}
public class EnumTest {
public static void main(String[] args) {
for (Sports sport : Sports.values()) {
// 遍历enum集合
// System.out.println(sport.ordinal());
// System.out.println(sport.compareTo(Sports.BASKETBALL));
// System.out.println(sport.equals(Sports.BASKETBALL));
// System.out.println(sport == Sports.BASKETBALL);
// System.out.println(sport.getDeclaringClass());
// System.out.println(sport.name());
}
for (String s : "BASKETBALL SOCCOR PINGPONG".split(" ")) {
Sports sport = Enum.valueOf(Sports.class, s);
System.out.println(sport);
}
}
}
像类一样的枚举
枚举类型可以像类那样拥有成员变量,构造方法、成员方法
public enum EnumTest3 {
BASKETBALL("Basketball is one of the most popular sports around the world."),
SOCCOR("SOCCOR is not the same in England and America."),
PINGPONG("PingPong is the best sports items in China.");
private String description;
private EnumTest3(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public static void main(String[] args) {
for (EnumTest3 sport : EnumTest3.values()) {
System.out.println(sport);
}
}
}
那么具体有什么用途?可以用来创建常量,这是我在公司的代码中看到的枚举类的用法。使用枚举的构造方法可以轻易的完成常量的设置,既有编码又有说明,是不是清晰?
public class EnumTest4 {
public enum Gender {
MAN(0, "男性"), WOMAN(1, "女性"), UNKNOWN(2, "不明");
private int code;
private String msg;
private Gender(int code, String msg) {
this.code = code;
this.msg = msg;
}
}
public static void main(String[] args) {
System.out.println(Gender.MAN.code);
}
}
神奇的values()
枚举的values方法非常特殊,你找不到它的源码,好像它是无中生有的。
这个案例通过比较枚举子类Software和枚举父类Enum的所有方法,得出结论:Software类拥有Enum类所有的方法,但前者还拥有后者没有的values方法,这个方法是编译器静态加上去的。
enum Software {
QQ, WECHAT, DUOKAN
}
public class EnumTest7 {
public static List<String> analyze(Class<?> enumClass) {
System.out.println("---------------------------");
System.out.println("泛型接口:");
for (Type t : enumClass.getGenericInterfaces()) {
System.out.println(t);
}
System.out.println("父类:");
// class java.lang.Enum
System.out.println(enumClass.getSuperclass());
System.out.println("方法:");
List<String> methods = new ArrayList<>();
for (Method m : enumClass.getMethods()) {
methods.add(m.getName());
}
System.out.println(methods);
System.out.println("---------------------------");
return methods;
}
public static void main(String[] args) {
List<String> softwareMethods = analyze(Software.class);
List<String> enumMethods = analyze(Enum.class);
System.out.println("子类是否有父类所有的方法:" + softwareMethods.containsAll(enumMethods));
System.out.println("除了父类的方法,子类还有哪些?");
softwareMethods.removeAll(enumMethods);
System.out.println(softwareMethods); // values
}
}
我们再来看一个案例,将枚举子类向上转型为父类,我们发现父类无法调用values方法。但Class类提供了一个getEnumConstants方法,用来获取枚举数组,达到类似values的效果。
enum Song {
YESTERDAY,
HEY_JUDY
}
public class EnumTest8 {
public static void main(String[] args) {
Enum e = Song.YESTERDAY;
// 编译错误,因为values是enum独有的,Enum没有,只能使用getEnmuConstants获取
// e.values();
for (Enum en : e.getClass().getEnumConstants()) {
System.out.println(en);
}
}
}