Java的枚舉類种吸,一般的常用方式是使用枚舉代表各類選項(xiàng),既限定了接受值的范圍呀非,又便于記憶坚俗。如使用枚舉定義星期幾、性別等等岸裙。
看一個(gè)最簡(jiǎn)單的枚舉:
public enum SimpleEnum {
MONDAY, TUESDAY;
}
在使用這個(gè)枚舉時(shí)猖败,我們可以使用以下的方法:
SimpleEnum.TUESDAY.name();
SimpleEnum.MONDAY.ordinal();
SimpleEnum.values();
SimpleEnum.valueOf("WEDNESDAY");
反編譯看一下:
Compiled from "SimpleEnum.java"
// 說明enum定義的枚舉,是java.lang.Enum類的子類
public final class jdk.test.Enum.SimpleEnum extends java.lang.Enum<jdk.test.Enum.SimpleEnum> {
private SimpleEnum(String s, int i)
{
super(s, i);
}
public static SimpleEnum[] values()
{
SimpleEnum asimpleenum[];
int i;
SimpleEnum asimpleenum1[];
System.arraycopy(asimpleenum = ENUM$VALUES, 0, asimpleenum1 = new SimpleEnum[i = asimpleenum.length], 0, i);
return asimpleenum1;
}
public static SimpleEnum valueOf(String s)
{
return (SimpleEnum)Enum.valueOf(jdk/test/Enum/SimpleEnum, s);
}
public static final SimpleEnum MONDAY;
public static final SimpleEnum TUESDAY;
private static final SimpleEnum ENUM$VALUES[];
static
{
MONDAY = new SimpleEnum("MONDAY", 0);
TUESDAY = new SimpleEnum("TUESDAY", 1);
ENUM$VALUES = (new SimpleEnum[] {
MONDAY, TUESDAY
});
}
}
再看一下java.lang.Enum類的源碼:
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
// Enum的私有屬性降允,name恩闻,結(jié)合字節(jié)碼,name屬性的值就是實(shí)例對(duì)象的變量名的String
private final String name;
public final String name() {
return name;
}
// 序號(hào)值剧董,從0開始 幢尚,static初始化塊中操作
private final int ordinal;
public final int ordinal() {
return ordinal;
}
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
public String toString() {
return name;
}
public final boolean equals(Object other) {
return this==other;
}
public final int hashCode() {
return super.hashCode();
}
/**
* Throws CloneNotSupportedException. This guarantees that enums
* are never cloned, which is necessary to preserve their "singleton"
* status.
*
* @return (never returns)
*/
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
public final int compareTo(E o) {
Enum<?> other = (Enum<?>)o;
Enum<E> self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;
}
@SuppressWarnings("unchecked")
public final Class<E> getDeclaringClass() {
Class<?> clazz = getClass();
Class<?> zuper = clazz.getSuperclass();
return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
}
public static <T extends Enum<T>> T valueOf(Class<T> enumType,
String name) {
T result = enumType.enumConstantDirectory().get(name);
if (result != null)
return result;
if (name == null)
throw new NullPointerException("Name is null");
throw new IllegalArgumentException(
"No enum constant " + enumType.getCanonicalName() + "." + name);
}
/**
* enum classes cannot have finalize methods.
*/
protected final void finalize() { }
/**
* prevent default deserialization
*/
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
throw new InvalidObjectException("can't deserialize enum");
}
private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("can't deserialize enum");
}
}
實(shí)際上看來,enum只是類的一種特殊形式翅楼,它實(shí)際上和普通的類沒有什么區(qū)別尉剩,只是JVM將他區(qū)別對(duì)待,讓他在定義時(shí)可以以特殊的形式來進(jìn)行毅臊,其他事情交給了JVM理茎。
而且,有趣的是褂微,Enum這個(gè)抽象類功蜓,我們是無法通過繼承它來創(chuàng)造自己的實(shí)現(xiàn)類的。
話說回來宠蚂,既然枚舉和正常類沒有什么區(qū)別式撼,那是不是可以像普通類定義構(gòu)造器,各種方法求厕,私有屬性呢著隆?
事實(shí)證明扰楼,當(dāng)然是可以的。
- 可以實(shí)現(xiàn)接口
- 可以定義屬性和方法
- 不可以顯式的調(diào)用其構(gòu)造器(因?yàn)槭莗rivate)
- 不可以繼承類(因?yàn)榘岛割惲耍?/li>
- 可以定義抽象方法美浦,且定義抽象方法時(shí)弦赖,enum反編譯是抽象類。
例:
public interface IEnum {
void test();
}
public enum MyEnum implements IEnum {
ONE(1) {
@Override
void what() {
// TODO Auto-generated method stub
}
},
TWO(2) {
@Override
void what() {
// TODO Auto-generated method stub
}
};
private int num;
abstract void what();
MyEnum(int num) {
this.setNum(num);
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public void test() {
System.out.println("test");
}
}
// decomplie
public abstract class MyEnum extends Enum
implements IEnum
{
private MyEnum(String s, int i)
{
super(s, i);
FIVE.num = 5;
}
abstract void what();
private MyEnum(String s, int i, int num)
{
super(s, i);
setNum(num);
FIVE.num = 5;
}
public MyEnum getFive()
{
return FIVE;
}
public int getNum()
{
return num;
}
public void setNum(int num)
{
this.num = num;
}
public void test()
{
System.out.println("test");
}
public static MyEnum[] values()
{
MyEnum amyenum[];
int i;
MyEnum amyenum1[];
System.arraycopy(amyenum = ENUM$VALUES, 0, amyenum1 = new MyEnum[i = amyenum.length], 0, i);
return amyenum1;
}
public static MyEnum valueOf(String s)
{
return (MyEnum)Enum.valueOf(jdk/test/Enum/MyEnum, s);
}
MyEnum(String s, int i, int j, MyEnum myenum)
{
this(s, i, j);
}
public static final MyEnum ONE;
public static final MyEnum TWO;
private int num;
private MyEnum FIVE;
private static final MyEnum ENUM$VALUES[];
static
{
ONE = new MyEnum("ONE", 0, 1) {
void what()
{
}
}
;
TWO = new MyEnum("TWO", 1, 2) {
void what()
{
}
}
;
ENUM$VALUES = (new MyEnum[] {
ONE, TWO
});
}
}
class MyEnum$1 extends MyEnum
{
void what()
{
}
MyEnum$1(String s, int i, int $anonymous0)
{
super(s, i, $anonymous0, null);
}
}
class MyEnum$2 extends MyEnum
{
void what()
{
}
MyEnum$2(String s, int i, int $anonymous0)
{
super(s, i, $anonymous0, null);
}
}