上一篇文章学习了多线程,至于为什么要写这篇文章是因为JDK使用Thread.State类定义了线程的几种状态。所以一起学习一下枚举类。
源码:
public enum State {
//新建
NEW,
//运行
RUNNABLE,
//阻塞
BLOCKED,
//等待
WAITING,
//超时等待
TIMED_WAITING,
//终止
TERMINATED;
}
首先明确一下学习大纲 什么是枚举类?为什么使用枚举类(特点)?枚举类的应用场景?如何定义枚举类?下面就一一展开去学习。
枚举类的理解:类的对象只有有限个,确定的。我们称此类为枚举类。
例如:
①星期:Monday(星期一)、…、Sunday(星期天)
②季节:Spring(春节)…Winter(冬天)
③性别:Man(男)、Woman(女)
当需要定义一组常量时,强烈建议使用枚举类
如果枚举类中只有一个对象,则可以作为单例模式的实现方式。
枚举类的属性:
①枚举类对象的属性不应允许被改动,所以应该使用private final 修饰
②枚举类的使用 private final 修饰的属性应该在构造器中为其赋值
③若枚举类显式的定义带参数的构造器,则在列出枚举值时也必须对应的传入参数。
代码如下:
class SeasonTest {
public static void main(String[] args) {
Season spring = Season.SPRING;
System.out.println(Season.class.getSuperclass());//默认继承Object类 -> class java.lang.Object
String seasonName = spring.getSeasonName();
System.out.println(seasonName);//春天
System.out.println(spring.toString());// Season{seasonName='春天', seasonDesc='春意盎然'}
}
}
//自定义枚举类
public class Season {
//季节的名字 1.声明的属性:private final修饰
private final String seasonName;
//季节的描述
private final String seasonDesc;
//2.私有化构造器,并给对象属性赋值
private Season(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
//3.提供当前枚举类的多个对象 public static final
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;
}
//需求②:重写toString()
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
}
代码如下:
//使用enum关键字定义枚举类
public enum Season1{
//1.提供当前枚举类的多个对象
//多个对象之间用逗号隔开,最后一个对象使用分号结束 public static final(省略)
SPRING("春天","春意盎然"),
SUMMER("夏天","夏日炎炎"),
AUTUMN("秋天","秋高气爽"),
WINTER("冬天","滴水成冰");
//2.声明枚举类属性 private final
private final String seasonName;
private final String seasonDesc;
//3.私有化构造方法并初始化属性值 private关键字可以省略
Season1(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
//需求①:获取枚举类对象的属性
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
①values():返回枚举类型的对象数组。该方法可以很方便地遍历所有枚举值
②valueOf():可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象 如果不是则抛出异常 IllegalArgumentException
③toString():返回当前枚举类对象常量的名称
①values()
class Season1Test {
public static void main(String[] args) {
// values() 返回枚举类型的对象数组
Season1[] values = Season1.values();
for (Season1 value : values) {
System.out.println(value);
System.out.println(value.getSeasonName());
}
}
}
执行结果:
SPRING
春天
SUMMER
夏天
AUTUMN
秋天
WINTER
冬天
②valueOf()
class Season1Test {
public static void main(String[] args) {
//valueOf() 可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象
Season1 autumn1 = Season1.valueOf("AUTUMN");
System.out.println(autumn1);
//如果没有该枚举类对象就报 IllegalArgumentException
//Season1 autumn2 = Season1.valueOf("AUTUMN1");
//System.out.println(autumn2);
}
}
执行结果:
AUTUMN
③toString()
class Season1Test {
public static void main(String[] args) {
Season1 autumn = Season1.AUTUMN;
System.out.println(autumn.toString());
}
}
执行结果:
AUTUMN
前面自定义枚举类我们都知道隐式继承的是Object类,那么使用enum关键字定义的枚举类是否也继承了Object类呢?
//枚举类隐式的继承了Enum -> class java.lang.Enum
System.out.println(Season1.class.getSuperclass());
System.out.println(Enum.class.getSuperclass());//class java.lang.Object
System.out.println(Object.class.getSuperclass());//null
通过上面对类的父类追踪也清楚了Java类是单继承,如果想要证明类可以实现多个接口
可以类.class.getInterfaces()。
情况一:实现接口,在enum类中实现抽象方法
interface info {
public abstract void show();
}
//使用enum关键字定义枚举类
public enum Season1 implements info{
//1.提供当前枚举类的多个对象 public static final(省略)
SPRING("春天","春意盎然"),
SUMMER("夏天","夏日炎炎"),
AUTUMN("秋天","秋高气爽"),
WINTER("冬天","滴水成冰");
//2.声明枚举类属性 private final
private final String seasonName;
private final String seasonDesc;
//3.私有化构造方法并初始化属性值 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("这是一个方法");
}
}
class Season1Test {
public static void main(String[] args) {
Season1 autumn = Season1.AUTUMN;
Season1 summer= Season1.SUMMER;
autumn.show();//这是一个方法
summer.show();//这是一个方法
}
}
上面情况无论哪一个枚举类型对象,调用show()都会打印这是一个方法。如果我想要每一个枚举类型对象都有自己的show(),可以参考情况二。
情况二:让枚举类的对象分别实现接口中的抽象方法
//变化的部分
SPRING("春天","春意盎然"){
@Override
public void show() {
System.out.println("春眠不觉晓");
}
},
SUMMER("夏天","夏日炎炎"){
@Override
public void show() {
System.out.println("明月别枝惊鹊,清风半夜鸣蝉。");
}
},
AUTUMN("秋天","秋高气爽"){
@Override
public void show() {
System.out.println("解落三秋叶");
}
},
WINTER("冬天","滴水成冰"){
@Override
public void show() {
System.out.println("北风吹雪四更初");
}
};
class Season1Test {
public static void main(String[] args) {
Season1 autumn = Season1.AUTUMN;
Season1 spring = Season1.SPRING;
autumn.show();
spring.show();
}
}
执行结果:
解落三秋叶
春眠不觉晓
枚举类用特有关键字enum修饰的类,本质是类,很特殊的类
类不能被创建new对象,不能被继承
枚举类中写的都是成员变量
至于应用场景,自己还没有接触到并且运用到项目的例子。不过在度娘的时候看见一片不错的文章小伙伴们可以大概浏览一下 枚举应用场景。