枚举是一个特殊的类,一般表示一组常量,比如一年有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 访问修饰符,所以外部无法调用。
- 枚举既可以包含具体方法,也可以包含抽象方法。 如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。