天天看点

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 访问修饰符,所以外部无法调用。
    • 枚举既可以包含具体方法,也可以包含抽象方法。 如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。