`

Effective Java(三)之小插曲:枚举剖析

阅读更多

      资料上说:enum是继承自java.lang.Enum的。我直接写了一下,连编译都通不过。后来又找资料才知道,这个继承是有编译器处理的。现在先直接拿下面的例子说事了:用java命令行直接查看编译好的WeekDay.class文件。

D:\workspace\enumtest\bin\com\lzw\enumtest>javap WeekDay
Compiled from "WeekDay.java"
public class com.lzw.enumtest.WeekDay extends java.lang.Enum{
    public static final com.lzw.enumtest.WeekDay MON;
    public static final com.lzw.enumtest.WeekDay TUE;
    public static final com.lzw.enumtest.WeekDay WED;
    public static final com.lzw.enumtest.WeekDay FUR;
    public static final com.lzw.enumtest.WeekDay FRI;
    public static final com.lzw.enumtest.WeekDay STA;
    public static final com.lzw.enumtest.WeekDay SUN;
    static {};
    public boolean getBoolean();
    public int getDay();
    public static com.lzw.enumtest.WeekDay[] values();
    public static com.lzw.enumtest.WeekDay valueOf(java.lang.String);
    com.lzw.enumtest.WeekDay(java.lang.String, int, int, com.lzw.enumtest.WeekDay);
}

      即便如此,想了解enum类型,还是要先了解一下java.lang.Enum类。跟进JDK 源码中,很容易发现Enum类的定义:

	public abstract class Enum<E extends Enum<E>> implements Comparable<E>,Serializable {
	
	}
	
	 public final int compareTo(E o) {
		Enum other = (Enum)o;
		Enum self = this;
		if (self.getClass() != other.getClass() && // optimization
				self.getDeclaringClass() != other.getDeclaringClass())
			throw new ClassCastException();
		return self.ordinal - other.ordinal;
	}

 在enum元素比较是比较它们的ordinal。源码的东西这里不用多说……

下面直接拿例子解析:

1、枚举类WeekDay.java

package com.lzw.enumtest;

public enum WeekDay {
	MON(1), TUE(2), WED(3), FUR(4), FRI(5) {
		// 重写,替换父的return false
		@Override
		public boolean getBoolean() {
			return true;
		}
	},
	STA(6), SUN(7);
	private int day;

	// 必须私有化构造方法 ,因为枚举类的成员都是static final的 ,不提供外部赋值
	private WeekDay(int day) {
		this.day = day;
	}

	public boolean getBoolean() {
		return false;
	}

	public int getDay() {
		return day;
	}
}

 

2、测试类TestJava1.java

package com.lzw.enumtest;

import java.util.EnumMap;
import java.util.Iterator;
import java.util.Map.Entry;

public class TestJava1 {
	public static void main(String[] args) {
		for (WeekDay day : WeekDay.values()) {
			// :枚举重写了ToString(),说以枚举变量的值是不带前缀的
			switch (day) {
			case MON:
				System.out.println("周一:" + day.getDay() + " index:"
						+ day.ordinal() + " boolean:" + day.getBoolean());
				break;
			case TUE:
				System.out.println("周二:" + day.getDay() + " index:"
						+ day.ordinal() + " boolean:" + day.getBoolean());
				break;
			case FRI:
				System.out.println("周五:" + day.getDay() + " index:"
						+ day.ordinal() + " boolean:" + day.getBoolean());
				break;
			default:
				break;
			}
		}

		EnumMap<WeekDay, String> enumMap = new EnumMap<WeekDay, String>(WeekDay.class);
		
		enumMap.put(WeekDay.WED, "周三");
		enumMap.put(WeekDay.SUN, "周日");
		
		Iterator<Entry<WeekDay, String>> iterator = enumMap.entrySet().iterator();
		
		for (; iterator.hasNext();) {
			Entry<WeekDay, String> entry = iterator.next();
			System.out.println(entry.getKey().name() + "__" + entry.getValue());
		}

	}

}

 

      很明显枚举的每一个元素都是其实例,并且是static的哦。每一个ordinal都不相同,这也是java.lang.Enum的compareTo方法告诉我们的:不同元素,其ordinal不同。

      至于values()方法,直接看上面的编译好的代码

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics