基本概念
Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。
Java 枚举类使用 enum 关键字来定义,各个常量使用逗号(,)来分割。枚举类和正常类一样,也可以有成员变量、实例方法、静态方法、抽象方法
。
比如列举一个颜色的枚举类,包含红、黄、蓝三个属性
public class test1 {
enum Color{
RED,
YELLOW,
BLUE
}
public static void main(String[] args) {
System.out.println(Color.RED);
System.out.println(RED);
}
}
每个枚举都是通过 Class 在内部实现的,且所有的枚举值都是 public static final 的。
以上的枚举类 Color 转化在内部类实现:
class Color
{
public static final Color RED = new Color();
public static final Color YELLOW= new Color();
public static final Color BLUE= new Color();
}
values(), ordinal() 和 valueOf() 方法
enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Seriablizable 和 java.lang.Comparable 两个接口。
values(), ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:
- values() 返回枚举类中所有的值。
- ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。
- valueOf()方法返回指定字符串值的枚举常量。
public class test1 {
enum Color{
RED,
YELLOW,
BLUE
}
public static void main(String[] args) {
// System.out.println(Color.RED);
// System.out.println(RED);
System.out.println(Arrays.toString(Color.values()));
System.out.println(YELLOW.ordinal());
System.out.println(Color.valueOf("YELLOW"));
}
}
输出:
1. 枚举类常量
//枚举类是一个特殊的class
//这个class相当于使用final static修饰,不能被继承
//他的构造方法强制被私有化,每一个枚举类有一个默认的构造方法private ColorEnum();
//所有的枚举都继承自java.lang.Enum类。由于 Java 不支持多继承,所以枚举对象不能再继承其他类
public enum Color {
//每个枚举变量都是枚举类Color的实例,相当于RED=new Color(1),按序号来。
//每个成员变量都是final static修饰
RED,YELLOW,BLUE
}
测试:
public static void main(String[] args) {
for (Color color : Color.values()) {
System.out.println(color+",ordinal:"+color.ordinal()+",name:"+color.name());
}
}
结果:
2. 带参数的枚举
public class test2 {
/**
* Monday (周一)
* Tuesday (周二)
* Wednesday (周三)
* Thursday (周四)
* Friday (周五)
* Saturday (周六)
* Sunday (周日)
*/
enum Week{
MONDAY(1),
TUESDAY(2),
WEDNESDAY(3),
THURSDAY(4),
FRIDAY(5),
SATURDAY(6),
SUNDAY(7);
private Integer num;
private Week(Integer num){
this.num=num;
}
public static Integer getNum(Week week){
return week.num;
}
}
public static void main(String[] args) {
System.out.println(Week.getNum(Week.FRIDAY));
}
}
结果:
3. 覆盖枚举的方法
public class test2 {
enum Week{
MONDAY(1),
TUESDAY(2),
WEDNESDAY(3),
THURSDAY(4),
FRIDAY(5),
SATURDAY(6),
SUNDAY(7);
private Integer num;
private Week(Integer num){
this.num=num;
}
public static Integer getNum(Week week){
return week.num;
}
@Override
public String toString() {
return this.name()+"_"+this.num;
}
}
public static void main(String[] args) {
for (Week week : Week.values()) {
System.out.println(week.toString());
}
}
}
结果:
4.在Switch中使用枚举
public class test2 {
enum Week{
MONDAY(1),
TUESDAY(2),
WEDNESDAY(3),
THURSDAY(4),
FRIDAY(5),
SATURDAY(6),
SUNDAY(7);
private Integer num;
private Week(Integer num){
this.num=num;
}
public static Integer getNum(Week week){
return week.num;
}
@Override
public String toString() {
return this.name()+"_"+this.num;
}
}
public static void main(String[] args) {
Week thursday = Week.THURSDAY;
switch (thursday){
case MONDAY:
System.out.println("星期一");
break;
case TUESDAY:
System.out.println("星期二");
break;
case WEDNESDAY:
System.out.println("星期三");
break;
case THURSDAY:
System.out.println("星期四");
break;
case FRIDAY:
System.out.println("星期五");
break;
case SATURDAY:
System.out.println("星期六");
break;
case SUNDAY:
System.out.println("星期天");
break;
default:
System.out.println("输入错误");
}
}
}
结果:
5.实现接口
我们创建的枚举类默认是被final修饰,并且默认继承了Enum类。因此不能再继承其他的类。但是可以去实现接口。
有这样一个判断场景。
if ("dog".equals(animalType)){
System.out.println("吃骨头");
} else if ("cat".equals(animalType)) {
System.out.println("吃鱼干");
} else if ("sheep") {
System.out.println("吃草");
}
怎样用枚举来消除掉 if/else 呐,看下面的代码:
先定义一个接口,里面有一个通用方法 eat()
public interface Eat {
//吃
String eat();
}
然后创建枚举类实现这个接口
public enum AnimalEnum implements Eat {
Dog(){
@Override
public void eat() {
System.out.println("吃骨头");
}
},
Cat() {
@Override
public void eat() {
System.out.println("吃鱼干");
}
},
Sheep() {
@Override
public void eat() {
System.out.println("吃草");
}
}
}
调用的时候只需要一行代码:
public class Test {
public static void main(String[] args) {
AnimalEnum.valueOf("Cat").eat(); // 吃鱼干
}
}
6.枚举类中定义抽象方法
枚举类除了可以实现接口外,还可以在枚举类中定义抽象方法,这样每个枚举的对象只要分别实现了此抽象方法即可。
enum Color{
RED{
public String getColor(){//枚举对象实现抽象方法
return "红色";
}
},
GREEN{
public String getColor(){//枚举对象实现抽象方法
return "绿色";
}
},
BLUE{
public String getColor(){//枚举对象实现抽象方法
return "蓝色";
}
};
public abstract String getColor();//定义抽象方法
}
public class Test{
public static void main(String[] args) {
for (Color c:Color.values()){
System.out.print(c.getColor() + "、");
}
}
}
7.枚举实现懒汉式单例
/**
* @Description: 枚举 线程安全
*/
public class SingletonExample {
/**
* 构造函数私有化,避免外部创建实例
*/
private SingletonExample(){}
private static SingletonExample getInstance() {
return Singleton.INSTANCE.getInstance();
}
private enum Singleton {
INSTANCE;
private SingletonExample instance;
// JVM 保证这个方法绝对只调用一次
Singleton() {
instance = new SingletonExample();
}
public SingletonExample getInstance() {
return instance;
}
}
}