枚举类
背景及定义
自定义枚举类与enmu对比
- 在上一篇java高级之多线程中,生命周期的线程的状态中,有这样的一段代码,分别代表线程的
新建状态
、运行状态
、阻塞状态
、等待状态
、超时等待状态
、终止状态
。
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
}
- 那么假如现在不用枚举类或者说,在枚举类的用法还没发行之前,我们想表示线程的这几种状态时,又该怎么写呢?经过一番思考,它应该符合以下几个条件:
- 这些状态是有限个的,也就是说我们设计的线程状态一共有6种;
- 这6种状态都应该是
State
类的实例; - 除下自己定义的这6种状态外,不应该在
State
类外面实例化一个状态,换句话说,状态一共就6种,并且已经在State类中实例化好了。那么该类的构造方法应该是私有private
的; - 状态应该是静态
static
的,这样可以通过类名直接调用; - 状态是常量,用
final
修饰。
public class State {
//私有的构造方法
private State(){
}
//实例化6种状态
public static final State NEW = new State();
public static final State RUNNABLE = new State();
public static final State BLOCKED = new State();
public static final State WAITING = new State();
public static final State TIMED_WAITING = new State();
public static final State TERMINATED = new State();
//想打印一下当前线程的名字
public static void printNowState(State state){
if(state == NEW)
System.out.println("NEW");
else if(state == RUNNABLE)
System.out.println("RUNNABLE");
else if(state == BLOCKED)
System.out.println("BLOCKED");
else if(state == WAITING)
System.out.println("WAITING");
else if(state == TIMED_WAITING)
System.out.println("TIMED_WAITING");
else if(state == TERMINATED)
System.out.println("TERMINATED");
}
}
class Teststate {
public static void main(String[] args) {
//新建状态
System.out.println("线程的新建状态" + State.NEW);
//打印出状态名,重写toString也打印不出来当前状态名字,因为toString方法没有参数。
State.printNowState(State.NEW);
}
}
枚举类
简单介绍
- 类的对象只有有限个,并且是确定的。例如:星期、季节、性别、线程状态等。
- 相对于自定义常量来说,枚举类更加直观,类型安全。
枚举类特点
-
私有化类的构造器,无法在类的外部创建对象;
-
枚举类的实例。声明为:
public static final
; -
枚举类对象的属性使用
private final
修饰,不允许被修改; -
枚举类的属性应该在构造器中为其赋值;
-
若枚举类显式的定义了带参数的构造器, 则在列出枚举值时也必须对应的传入参数。
使用说明
- 枚举类使用的是
enum
关键字,继承自java.lang.Enum
,且无法被继承; - 必须在枚举类的第一行声明枚举类对象;
- 枚举类的所有实例必须在枚举类中显式列出,(用“,” 分隔、用“ ;” 结尾);
- 定义的每个实例都是引用类型的唯一实例;
- 只能定义出
enum
的实例,而无法通过new
操作符创建enum
的实例; - 列出的实例系统会自动添加
public static final
修饰; - 使用enum变量的时候,【类名.变量名】;
- 可以将
enum
类型用于switch
语句。
枚举类反编译
- 如上使用枚举类定义线程状态时,编译器编译出的
class
文件类似于这样:
//该类继承自Enum,被标记为final class
public final class State extends Enum {
//每个实例均为全局唯一,均为static final修饰。
public static final State NEW = new State();
public static final State RUNNABLE = new State();
....
public static final State TERMINATED = new State();
// 构造器私有化,在类的外部无法调用new操作符。
private State() {
}
}
主要方法
-
如上,我们定义出线程状态的枚举类后,使用枚举类State的常用方法有:
-
方法实战
public static void main(String[] args) { //返回枚举类对象的名字,枚举类对象的名字不用重写toString System.out.println(State.NEW.toString()); System.out.println("============我是分隔符============="); //返回所有的枚举类对象构成的数组 State[] states = State.values(); for (int i = 0; i < states.length; i++) { System.out.println(states[i]); } System.out.println("============我是分隔符============="); //valueOf(String objName):返回枚举类中对象名是objName的对象。传入的objName应该存在,否则抛异常IllegalArgumentException State state = State.valueOf("NEW"); System.out.println(state); System.out.println("============我是分隔符============="); //枚举的switch用法 State scase = State.BLOCKED; switch (scase) { case NEW: System.out.println("我的线程状态是" + scase.toString()); break; case RUNNABLE: System.out.println("我的线程状态是" + scase.toString()); break; case BLOCKED: System.out.println("我的线程状态是" + scase.toString()); break; case WAITING: System.out.println("我的线程状态是" + scase.toString()); break; case TIMED_WAITING: System.out.println("我的线程状态是" + scase.toString()); break; case TERMINATED: System.out.println("我的线程状态是" + scase.toString()); break; default: throw new RuntimeException("查不到定义的线程状态" + scase.toString()); } }
-
控制台的输出
总结
- 枚举类的出现是为了解决类的对象是有限个并且是确定的情况;
- 构造器私有化;
- 必须首行声明枚举类对象,逗号隔开,分号结尾。
原创不易,欢迎转载,转载时请注明出处,谢谢!