枚舉是一個特殊的類,一般表示一組常量,比如一年有4個季節,一年有12個月份,一個星期天有7天等。
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 通路修飾符,是以外部無法調用。
- 枚舉既可以包含具體方法,也可以包含抽象方法。 如果枚舉類具有抽象方法,則枚舉類的每個執行個體都必須實作它。