Android 下列舉型使用、及與 int 轉換的困惑

91program發表於2014-09-16

本論壇將全面搬家到:http://www.cnblogs.com/91program,請大家以後來這裡看看。


在 C/C++ 環境下,已經習慣使用列舉型常量,但在 Android 下使用時發現列舉與 C/C++ 下是完全不同的。

Android 下,列舉其實是類。
使用感覺困難,主要是列舉與 int 之間的轉換。如果列舉的定義如下 weekday 所示,還可以通過 ordinal() 和 values()[] 方法進行轉換。
但不幸的是,我使用的是如下 weekday_2 所示的列舉型別,我是沒有找到對應的轉換方法。
最後沒有辦法,將列舉修改為一般的常量定義,如下:
public static final short MAX_BUFFER_SIZE = 2048;

public class Test {
	public enum weekday
	{
	    sun,
	    mou,
	    tue,
	    thu,
	    fri,
	    sat,
	    wed,
	};
	
	public enum weekday_2
	{
	    sun(0x1),
	    mou(0x2),
	    tue(0x3),
	    thu(0x4),
	    fri(0x5),
	    sat(0x6),
	    wed(0x7),
	    large(0x99);		// 如果增加此值,通過 ordinal() 方法得到的值是多少?
	
	    private int iSet;
	    weekday_2(int iValue) {
	        this.iSet = iValue;
	    }
	
	    public int Get() {
	        return this.iSet;
	    }
	};
}


對於上面兩個列舉定義 weekday 和 weekday_2:
int x = weekday.sun.ordinal();
weekday sun = weekday.values()[x];

int x = weekday_2.sun.ordinal();
weekday_2 sun = weekday_2.values()[x];
有什麼差別?除了 weekday_2 中的 large 成員外,其它成員的值是否相同?


void TestEnumValue() {
	TstEnum.weekday day = TstEnum.weekday.sun;
	TstEnum.weekday_2 day2 = TstEnum.weekday_2.sun;
	TstEnum.weekday_2 day2_large = TstEnum.weekday_2.large;
	
	int iDay = day.ordinal();
	int iDay2 = day2.ordinal();
	int iDay2Large = day2_large.ordinal();


    System.out.println("Enum Test" + "value of sun : " + Integer.toString(iDay) + "/" + Integer.toString(iDay2)
    		+ ". Large: " + Integer.toString(iDay2Large));
}


執行後輸出的結果是: Enum Testvalue of sun : 0/0. Large: 7
weekday_2 的成員 sun 並未輸出其真實的數值,而是輸出了下標。
對應之,weekday.values()[x]; 也是下標。若知道 weekday_2 的一個變數值是: 整型 0x99, 想轉成對應的列舉。如果使用 weekday.values()[0x99] 則會直接越界。


(1)  執行:javac Test.java
編譯沒有出錯即可。


(2) 執行: javap Test
得到以下的輸出:
Compiled from "Test.java"
public class Test {
  int x;
  Test$weekday sun;
  public Test();
}


(3) 執行: javap Test$weekday
得到以下輸出:
Compiled from "Test.java"
public final class Test$weekday extends java.lang.Enum<Test$weekday> {
  public static final Test$weekday sun;
  public static final Test$weekday mou;
  public static final Test$weekday tue;
  public static final Test$weekday thu;
  public static final Test$weekday fri;
  public static final Test$weekday sat;
  public static final Test$weekday wed;
  public static Test$weekday[] values();
  public static Test$weekday valueOf(java.lang.String);
  static {};
}


(4) 執行: javap Test$weekday_2
得到以下輸出:
Compiled from "Test.java"
public final class Test$weekday_2 extends java.lang.Enum<Test$weekday_2> {
  public static final Test$weekday_2 sun;
  public static final Test$weekday_2 mou;
  public static final Test$weekday_2 tue;
  public static final Test$weekday_2 thu;
  public static final Test$weekday_2 fri;
  public static final Test$weekday_2 sat;
  public static final Test$weekday_2 wed;
  public static Test$weekday_2[] values();
  public static Test$weekday_2 valueOf(java.lang.String);
  public int Get();
  static {};
}


從以上反編譯出來的程式碼可以得出以下結論: 
(1) weekday 和 weekday_2 列舉類是final class,即不能被繼承,而它本身是繼承於 Enum
(2) 列舉值是 weekday 或 weekday_2 物件,而且是 static final 修飾的

相關文章