1. 程式人生 > >關於JAVA列舉類和Enum方法

關於JAVA列舉類和Enum方法

1.列舉類入門

Java列舉類是從Java5開始支援的。

列舉類的構造方法是用private修飾的。列舉類的所有例項必須在類的第一行列出,否則這個列舉類不會產生物件。

而且這些例項都是public static void.

每個列舉類都有一個values方法,該方法可以遍歷列舉類的所有例項

public class Test {

public static void tell(Season s)
{
    switch(s)
    {
    case Spring:
        System.out.println(s+"春天");
        break;
    case Summer:System.out.println(s+"夏天");
        break;
    case Fall:System.out.println(s+"秋天");
        break;
    case Winter:System.out.println(s+"冬天");
        break;
    }

}

public static void main(String[] args) {

    for(Season s:Season.values())
    {
        System.out.println(s);
    }
    tell(Season.Fall);

}

}

enum Season { Spring,Summer,Fall,Winter; }

2.列舉類的構造方法和物件

列舉類的構造方法是private,所以不能使用new建立物件

可以使用Enum.valueOf(Class c,String s);建立物件

public class Test {

public static void main(String[] args) {

    Season s=Enum.valueOf(Season.class, "Summer");
    System.out.println(s);

}

}

enum Season { Spring,Summer,Fall,Winter; } 一旦為列舉類定義了帶引數的構造方法後,列舉列舉類就必須對應的傳入引數

public class Test {

public static void main(String[] args) {

    Season s=Enum.valueOf(Season.class, "Summer");
    System.out.println(s.name);

}

}

enum Season { Spring(“春天”),Summer(“夏天”),Fall(“秋天”),Winter(“冬天”); public String name; private Season(String name) { this.name=name; } }

3.列舉類實現介面

與普通類一樣,列舉類實現介面,則必須實現介面中所有的方法

public class Test {

public static void main(String[] args) {

    Season s=Enum.valueOf(Season.class, "Summer");
    System.out.println(s.name);
    s.printInfo();

}

}

enum Season implements Infomation { Spring(“春天”),Summer(“夏天”),Fall(“秋天”),Winter(“冬天”); public String name; private Season(String name) { this.name=name; } @Override public void printInfo() { System.out.println(name);

}

} interface Infomation { void printInfo(); }

也可以使用匿名內部類的方法為每一個列舉類物件實現介面

public class Test {

public static void main(String[] args) {

    Season s=Enum.valueOf(Season.class, "Summer");
    System.out.println(s.name);
    s.printInfo();

}

}

enum Season implements Infomation { Spring(“春天”){

    @Override
    public void printInfo() {
        // TODO Auto-generated method stub
        System.out.println("春天溫暖");

    }

},Summer("夏天")
{

    @Override
    public void printInfo() {
        // TODO Auto-generated method stub
        System.out.println("夏天炎熱");
    }

},Fall("秋天")
{

    @Override
    public void printInfo() {
        // TODO Auto-generated method stub
        System.out.println("秋天涼爽");
    }

},Winter("冬天"){

    @Override
    public void printInfo() {
        // TODO Auto-generated method stub
        System.out.println("冬天寒冷");
    }

};
public String name;
private Season(String name)
{
    this.name=name;
}

} interface Infomation { void printInfo(); }

4.包含抽象方法的列舉類

包含抽象方法列舉類,要例項化物件的話,就得讓每個物件實現抽象方法

public class Test {

public static void main(String[] args) {

    Season s=Enum.valueOf(Season.class, "Summer");
    System.out.println(s.name);
    s.printInfo();
    s.whatToDo();

}

}

enum Season implements Infomation { Spring(“春天”){

    @Override
    public void printInfo() {
        // TODO Auto-generated method stub
        System.out.println("春天溫暖");

    }

    @Override
    public void whatToDo() {
        // TODO Auto-generated method stub
        System.out.println("我去春遊");

    }

},Summer("夏天")
{

    @Override
    public void printInfo() {
        // TODO Auto-generated method stub
        System.out.println("夏天炎熱");
    }

    @Override
    public void whatToDo() {
        // TODO Auto-generated method stub
        System.out.println("我去游泳");
    }

},Fall("秋天")
{

    @Override
    public void printInfo() {
        // TODO Auto-generated method stub
        System.out.println("秋天涼爽");
    }

    @Override
    public void whatToDo() {
        // TODO Auto-generated method stub
        System.out.println("我去玩乒乓球");
    }

},Winter("冬天"){

    @Override
    public void printInfo() {
        // TODO Auto-generated method stub
        System.out.println("冬天寒冷");
    }

    @Override
    public void whatToDo() {
        // TODO Auto-generated method stub
        System.out.println("我去賞雪觀梅");
    }

};
public String name;
private Season(String name)
{
    this.name=name;
}
public abstract void whatToDo();

} interface Infomation { void printInfo(); }

Enum作為Sun全新引進的一個關鍵字,看起來很象是特殊的class, 它也可以有自己的變數,可以定義自己的方法,可以實現一個或者多個介面。 當我們在宣告一個enum型別時,我們應該注意到enum型別有如下的一些特徵。

  1.它不能有public的建構函式,這樣做可以保證客戶程式碼沒有辦法新建一個enum的例項。

  2.所有列舉值都是public , static , final的。注意這一點只是針對於列舉值,我們可以和在普通類裡面定義 變數一樣定義其它任何型別的非列舉變數,這些變數可以用任何你想用的修飾符。

  3.Enum預設實現了java.lang.Comparable介面。

  4.Enum覆載了了toString方法,因此我們如果呼叫Color.Blue.toString()預設返回字串”Blue”.

  5.Enum提供了一個valueOf方法,這個方法和toString方法是相對應的。呼叫valueOf(“Blue”)將返回Color.Blue.因此我們在自己重寫toString方法的時候就要注意到這一點,一把來說應該相對應地重寫valueOf方法。

  6.Enum還提供了values方法,這個方法使你能夠方便的遍歷所有的列舉值。

  7.Enum還有一個oridinal的方法,這個方法返回列舉值在列舉類種的順序,這個順序根據列舉值宣告的順序而定,這裡Color.Red.ordinal()返回0。

  瞭解了這些基本特性,我們來看看如何使用它們。

  1.遍歷所有有列舉值. 知道了有values方法,我們可以輕車熟路地用ForEach迴圈來遍歷了列舉值了。

  for (Color c: Color.values())   System.out.println(“find value:” + c);

  2.在enum中定義方法和變數,比如我們可以為Color增加一個方法隨機返回一個顏色。

  public enum Color {   Red,   Green,   Blue;

  /*   *定義一個變量表示列舉值的數目。   *(我有點奇怪為什麼sun沒有給enum直接提供一個size方法).   */   private static int number = Color.values().length ;

  /**   * 隨機返回一個列舉值   @return a random enum value.   */   public static Color getRandomColor(){   long random = System.currentTimeMillis() % number;   switch ((int) random){    case 0:     return Color.Red;    case 1:     return Color.Green;    case 2:     return Color.Blue;    default : return Color.Red;   }   }   }

  可以看出這在列舉型別裡定義變數和方法和在普通類裡面定義方法和變數沒有什麼區別。唯一要注意的只是變數和方法定義必須放在所有列舉值定義的後面,否則編譯器會給出一個錯誤。

  3.覆載(Override)toString, valueOf方法

  前面我們已經知道enum提供了toString,valueOf等方法,很多時候我們都需要覆載預設的toString方法,那麼對於enum我們怎麼做呢。其實這和覆載一個普通class的toString方法沒有什麼區別。

  ….   public String toString(){   switch (this){   case Red:    return “Color.Red “;   case Green:    return “Color.Green “;   case Blue:    return “Color.Blue “;   default:    return “Unknow Color “;   }   }   ….

  這時我們可以看到,此時再用前面的遍歷程式碼打印出來的是

  Color.Red   Color.Green   Color.Blue

  而不是

  Red   Green   Blue.

  可以看到toString確實是被覆載了。一般來說在覆載toString的時候我們同時也應該覆載valueOf方法,以保持它們相互的一致性。

  4.使用建構函式

  雖然enum不可以有public的建構函式,但是我們還是可以定義private的建構函式,在enum內部使用。還是用Color這個例子。

  public enum Color {   Red( “This is Red “),   Green( “This is Green “),   Blue( “This is Blue “);

  private String desc;

  Color(String desc){   this.desc = desc;   }

  public String getDesc(){   return this.desc;   }

  }

  這裡我們為每一個顏色提供了一個說明資訊, 然後定義了一個建構函式接受這個說明資訊。

  要注意這裡建構函式不能為public或者protected, 從而保證建構函式只能在內部使用,客戶程式碼不能new一個列舉值的例項出來。這也是完全符合情理的,因為我們知道列舉值是public static final的常量而已。

  5.實現特定的介面

  我們已經知道enum可以定義變數和方法,它要實現一個介面也和普通class實現一個介面一樣,這裡就不作示例了。

  6.定義列舉值自己的方法。

  前面我們看到可以為enum定義一些方法,其實我們甚至可以為每一個列舉值定義方法。這樣,我們前面覆載 toString的例子可以被改寫成這樣。

  public enum Color {   Red {   public String toString(){    return “Color.Red “;   }   },   Green {   public String toString(){    return “Color.Green “;   }   },   Blue{   public String toString(){    return “Color.Blue “;   }   };   }

  從邏輯上來說這樣比原先提供一個“全域性“的toString方法要清晰一些。

  總的來說,enum作為一個全新定義的型別,是希望能夠幫助程式設計師寫出的程式碼更加簡單易懂,個人覺得一般也不需要過多的使用enum的一些高階特性,否則就和簡單易懂的初衷想違背了。

個人理解:列舉類用來進行約束,不能new物件,然後是限定了範圍。