天天看點

java 基礎 淺談枚舉類enum

枚舉是一個特殊的類,一般表示一組常量,比如一年有4個季節,一年有12個月份,一個星期天有7天等。

java枚舉類使用enum關鍵字來定于,各個常量使用逗号**,**來格式。

java 基礎 淺談枚舉類enum

從上面可以得到

  • 枚舉是從1.5版本開始的
  • 無論季節還是月份,都是有限的常量。同時月份,季節這些常量是不可變的。

枚舉有什麼用,我們暫時先不提,也是從代碼開始了解。

在1.5之前因為沒有Enum,是以需要手動寫枚舉類。

public class Test  {

	public static void main(String[] args) {
		System.out.println(Session.SPRING);


	}
	}	
	

class Session{
	private final   String sessionName; 
	private final   String desc;
	public Session(String sessionName, String desc) {
		super();
		this.sessionName = sessionName;
		this.desc = desc;
	}
	
   @Override
	public String toString() {
		return "Session [sessionName=" + sessionName + ", desc=" + desc + "]";
	}

public static final Session SPRING=new Session("春天", "春暖花開");
   p Session SUMMER=new Session("夏天", "夏日灼熱");
   public static final Session AUTUMN=new Session("秋天", "秋高氣爽");
   public static final Session WINTER=new Session("冬天", "冬日之陽");
   	
}
//輸出
Session [sessionName=春天, desc=春暖花開]
           

前面所言不可變的常量,其實看這個代碼就多少了解一點,我們在建立的常量的時候一般都會選擇觀其而知其意。是以spring 這樣的名一般我們就會代表是春天。是以這樣的變量我們一般定義的時候都會用final進行修飾,畢竟不可能你用spring 代表夏天吧。

因為在程式設計的時候我們多次需要類似的類,是以jdk1.5版本的時候就添加了枚舉類。

public class Test  {

	public static void main(String[] args) {
		System.out.println(Session.SPRING);// 調用對象如果沒有重新string會發揮常量對象的名
		Session[] searr=Session.values();//  枚舉類的values 方法傳回一個枚舉常量對象的數組
		for(int i=0;i<searr.length;i++) {
			System.out.println(searr[i]);
		}
		System.out.println(Session.valueOf("SPRING"));// SPRING  取出這個對象,如果沒有就會報錯
		
		System.out.println(Session.SPRING.getDesc());
		
		System.out.println(Session.AUTUMN.ordinal());//2  ordinal 方法傳回索引值


	}
	}	
	

enum Session{
	
  SPRING("春天", "春暖花開"),SUMMER("夏天", "夏日灼熱"),AUTUMN("秋天", "秋高氣爽"),WINTER("冬天", "冬日之陽");
	private final   String sessionName; 
	private final   String desc;
	private Session(String sessionName, String desc) {//這個地方必須用私有,也可以不寫預設是private,如果寫public,project會報錯

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


           

當然枚舉也可是實作接口,如上面所示不同季節肯定有不同的事情的。

public class Test  {

	public static void main(String[] args) {
		System.out.println(Session.SPRING);// 調用對象如果沒有重新string會發揮常量對象的名
		Session[] searr=Session.values();//  枚舉類的values 方法傳回一個枚舉常量對象的數組
		for(int i=0;i<searr.length;i++) {
			System.out.println(searr[i]);
		}
		System.out.println(Session.valueOf("SPRING"));// SPRING  取出這個對象,如果沒有就會報錯
		
		System.out.println(Session.SPRING.getDesc());
	
		Session.SPRING.play();
	


	}
	}	
	
interface info{
	void play();
}
enum Session implements info{
	
	SPRING("春天", "春暖花開"){
	
		public void g() {
			
		}
		@Override
		public void play() {
			System.out.println("我們去踏青");
			
		}
	},SUMMER("夏天", "夏日灼熱"){
		@Override
		public void play() {
			// TODO Auto-generated method stub
			System.out.println("我們去遊泳");
			
		}
	},AUTUMN("秋天", "秋高氣爽"){
		@Override
		public void play() {
			// TODO Auto-generated method stub
			System.out.println("我們去看收獲");
			
		}
	},WINTER("冬天", "冬日之陽"){
		@Override
		public void play() {
			// TODO Auto-generated method stub
			System.out.println("我們去滑雪");
			
		}
	};
	private final   String sessionName; 
	private final   String desc;
	private Session(String sessionName, String desc) {//這個地方必須用私有,也可以不寫預設是private,如果寫public,project會報錯

		this.sessionName = sessionName;
		this.desc = desc;
	}

	public String getSessionName() {
		return sessionName;
	}
	public String getDesc() {
		return desc;
	}

	
}
           

當然枚舉類也可以簡單的什麼一些沒有屬性。比如thread的狀态

public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }
           

我們檢視器枚舉中的常量

public class Test  {

	public static void main(String[] args) {
		State[] arr= Thread.State.values();
		for(State s: arr) {
			System.out.println(s);
		}

	}
	}	
//輸出
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED

           

總結:

  • 枚舉類中的聲明的叫做成員。不要叫做常量,雖然前面說如果需要一組常量,而常量又是一定的,建議使用枚舉。但是枚舉卻稱之為成員。因為其不可變,是以避免了随意建立對象。
  • 枚舉類成員
    • 枚舉跟普通類一樣可以用自己的變量、方法和構造函數,構造函數隻能使用 private 通路修飾符,是以外部無法調用。
    • 枚舉既可以包含具體方法,也可以包含抽象方法。 如果枚舉類具有抽象方法,則枚舉類的每個執行個體都必須實作它。