类的对象只有有限个,确定的
例如:星期、季节、支付方式、
订单状态:Nonpayment(未付款)、 Paid(已付款) 、Delivered (已发货)、 Return (退货)、Checked (已确认 )、Fulfilled (已配货)
就职状态、
线程状态:
BLOCKED
一个线程的线程状态阻塞等待监视器锁定
NEW
线程尚未启动的线程状态
RUNNABLE
可运行线程的线程状态
TERMINATED
终止线程的线程状态
TIMED_WAITING
具有指定等待时间的等待线程的线程状态
WAITING
等待线程的线程状态
什么时候使用枚举类
需要定义一组常量时,如果枚举类中只有一个对象,则可以作为单例模式的实现方式
1)出于类型安全考虑,没用枚举类之前,常用静态常量来表示
对于性别的表示,
public static final int MAN = 0;
public static final int WOMAN = 1;
其一,这些变量完全可用来做加减运算,当然我们原意并非如此
其二,意义不明,当我们debug的时候,本来想输出‘男’,结果输出0
2)代码更优雅
一个大一些的程序里面,可能要用到成百上千的静态常量,如果全写在一个文件里面,容易造成命名混淆,程序读起来也比较麻烦
3)枚举类能方便我们定义自己想要的类型
枚举便于记忆和使用,并且相当于一个接口。使用时只需要封装内部的数据类型,并且限定数据域。而且对于不同的枚举变量,可以调用不同的处理方法
class Season{ // 1.声明Season对象的属性 private String seasonName; private String seasonDesc; // 2.私有化构造器 private Season(String seasonName, String seasonDesc){ this.seasonName = seasonName; this.seasonDesc = seasonDesc; } // 3.提供枚举类的对象 public static final Season SPRING = new Season("春天","春暖花开"); public static final Season SUMMER = new Season("夏天","夏日炎炎"); public static final Season AUTUMN = new Season("秋天","秋高气爽"); public static final Season WINTER = new Season("冬天","冰天雪地"); public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } @Override public String toString() { return "Season{" + "seasonName='" + seasonName + '\'' + ", seasonDesc='" + seasonDesc + '\'' + '}'; } } public class test { public static void main(String[] args) { Season spring = Season.SPRING; System.out.println(spring); } }
Season1是默认继承java.lang.Enum ,则不能继承其他类了,而且默认是final类
enum Season1 implements info { // 实现接口方式二 让枚举类的对象分别实现接口中的抽象方法 SPRING("春天", "春暖花开"){ // ordinal() 0 @Override public void show() { System.out.println("这是春天"); } }, // 相当于 匿名内部类 SUMMER("夏天", "夏日炎炎"){ // 1 @Override public void show() { System.out.println("这是夏天"); } }, AUTUMN("秋天", "秋高气爽"){// 2 @Override public void show() { System.out.println("这是秋天"); } }, WINTER("冬天", "冰天雪地"){// 3 @Override public void show() { System.out.println("这是冬天"); } }, WUCAN { // 4 @Override public void show() { System.out.println("无参"); } }; private String seasonName; private String seasonDesc; private Season1() { } private Season1(String seasonName, String seasonDesc) { this.seasonName = seasonName; this.seasonDesc = seasonDesc; } public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } // 实现接口 方式一 /* @Override public void show() { System.out.println("相同的行为"); }*/ } interface info { void show(); } public class test2 { public static void main(String[] args) { Season1 autumn = Season1.AUTUMN; System.out.println(autumn);// toString() System.out.println(Season1.class.getSuperclass()); Season1[] values = Season1.values(); for (int i = 0; i < values.length; i++) { System.out.println(values[i]); values[i].show(); } Season1 winter = Season1.valueOf("WINTER"); System.out.println(winter);// WINTER Thread.State[] values1 = Thread.State.values(); for (int i = 0; i < values1.length; i++) { System.out.println(values1[i]); } } }
// 如果枚举类 没有实现接口,结果和自定义枚举类是一样的 enum Season1 { SPRING("春天", "春暖花开"),// 相当于 public static final Season SPRING = new Season("春天","春暖花开"); SUMMER("夏天", "夏日炎炎"), AUTUMN("秋天", "秋高气爽"), WINTER("冬天", "冰天雪地"), WUCAN ; private String seasonName; private String seasonDesc; private Season1() { } private Season1(String seasonName, String seasonDesc) { this.seasonName = seasonName; this.seasonDesc = seasonDesc; } public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } } public class test2 { public static void main(String[] args) { Season1 autumn = Season1.AUTUMN; System.out.println(autumn.name()); System.out.println(autumn); // 输出枚举对象的次序,从0开始 System.out.println(autumn.ordinal());// 2 Season1 s = Season1.SPRING; System.out.println(s.compareTo(autumn));// -2 System.out.println(s.getDeclaringClass());// class test.Season1 System.out.println(s.getClass());// class test.Season1 System.out.println(autumn.getClass());// class test.Season1 } }
toString() 返回枚举对象常量的名称
/** * 用switch重写toString方法,提高代码健壮性 * @return */ @Override public String toString() { //switch支持Enum类型 switch (this) { case MONDAY: return "今天星期一"; case TUESDAY: case WEDNESDAY: return "今天星期三"; case THURSDAY: return "今天星期四"; case FRIDAY: return "今天星期五"; case SATURDAY: return "今天星期六"; case SUNDAY: return "今天星期日"; default: return "Unknow Day"; } }
values() 返回枚举类型的对象数组 // javap Season1.class 可以看到
valueOf(String str) 可以把一个字符串转为对应的枚举类对象
name 枚举常量的名称,建议优先使用toString
ordinal 得到当前枚举常量的次序
compareTo return self.ordinal() - other.ordinal()
getDeclaringClass 得到枚举常量所属枚举类型的Class对象,用它来判断两个枚举常量是否属于同一个枚举类型
// 以上 实现接口的枚举 public class test2 { public static void main(String[] args) { Season1 autumn = Season1.AUTUMN; System.out.println(autumn.name()); System.out.println(autumn); // 输出枚举对象的次序,从0开始 System.out.println(autumn.ordinal());// 2 Season1 s = Season1.SPRING; System.out.println(s.compareTo(autumn));// -2 System.out.println(s.getDeclaringClass());// class test.Season1 System.out.println(s.getClass());// class test.Season1$1 System.out.println(autumn.getClass());// class test.Season1$3 } }
clone 枚举类型不能被clone,为了防止子类实现克隆方法,Enum实现了仅抛出 CloneNotSupportedException异常的不变Clone()
switch 使用枚举类型对象,case 使用 枚举常量
public static void main(String[] args) { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); try { System.out.println("请输入1-7"); int i = Integer.parseInt(br.readLine()); switch (i) { case 1 : System.out.println(Week.MONDAY); printWeek(Week.MONDAY); break; case 2 : System.out.println(Week.TUESDAY); printWeek(Week.TUESDAY); break; case 3 : System.out.println(Week.WEDNESDAY); printWeek(Week.WEDNESDAY); break; case 4 : System.out.println(Week.THURSDAY); printWeek(Week.THURSDAY); break; case 5 : System.out.println(Week.FRIDAY); printWeek(Week.FRIDAY); break; case 6 : System.out.println(Week.SATURDAY); printWeek(Week.SATURDAY); break; case 7 : System.out.println(Week.SUNDAY); printWeek(Week.SUNDAY); break; } } catch (IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static void printWeek(Week week) { switch (week) { case MONDAY : System.out.println(Week.MONDAY.getWeekName()); break; case TUESDAY: System.out.println(Week.TUESDAY.getWeekName()); break; case WEDNESDAY: System.out.println(Week.WEDNESDAY.getWeekName()); break; case THURSDAY: System.out.println(Week.THURSDAY.getWeekName()); break; case FRIDAY: System.out.println(Week.FRIDAY.getWeekName()); break; case SATURDAY: System.out.println(Week.SATURDAY.getWeekName()); break; case SUNDAY: System.out.println(Week.SUNDAY.getWeekName()); break; } } enum Week { MONDAY("星期一"), TUESDAY("星期二"), WEDNESDAY("星期三"), THURSDAY("星期四"), FRIDAY("星期五"), SATURDAY("星期六"), SUNDAY("星期日"); private final String weekName; Week(String weekName) { this.weekName = weekName; } public String getWeekName() { return weekName; } }
equals(),枚举类型中可以直接使用== 来比较,Enum中的equals也是直接使用==来实现的,它的存在是在Set List Map中使用,equals是不可变的
其中 ==
运算符用于比较状态,并且如果两个值均为null 都不会引发 NullPointerException。相反,如果使用equals方法,将抛出 NullPointerException:
Pizza.PizzaStatus pizza = null; System.out.println(pizza.equals(Pizza.PizzaStatus.DELIVERED));//空指针异常 System.out.println(pizza == Pizza.PizzaStatus.DELIVERED);//正常运行
Week status = Week.MONDAY; Week status2 = Week.TUESDAY; Week status3 = Week.MONDAY; System.out.println(status==status3);// true System.out.println(status.equals(status3));// true System.out.println(status==status2);// false System.out.println(status.equals(status2));// false
持续更新。。。