目录

  • 一、 为什么要命名用枚举
  • 1.1需求:
  • 1.2 第一种实现:
  • 1.3 第二种实现:
  • 二、枚举定义
  • 2.1 创建枚举类
  • 2.2 特点
  • 三、枚举的应用
  • 3.1常量
  • 3.2 可以应用到switch当中
  • 3.3 有参数的枚举常量对象
  • 3.4 可以重写toString 方法
  • 3.5 枚举类可以实现接口
  • 3.6 在接口中:枚举类
  • 3.7 枚举可用放到集合当中
  • 四、父类java.lang.Enum
  • 五、枚举为什么是线程安全的?


一、 为什么要命名用枚举

1.1需求:

玩游戏有上下左右 ,请创建一个类,定义上下左右四个常量

java定义枚举类型key value 形式 java枚举的定义_数据结构

1.2 第一种实现:

public class GameStaticFinal {
    //上
    public  static  final int  UP = 1; 
    //下
    public  static  final int DOWN = 2;
    //左
    public  static  final int LEFT = 3;
    //右
    public  static final  int RIGHT = 4;
}

缺点:

  1. 必须要写static final 这两个关键字不能忘记!
  2. 1, 2, 3 ,4 这名语义不能 “见闻知义” , 如果在输出结果中,打印1234

1.3 第二种实现:

不见闻知义: 可以改成字符串:

public class GameStaticFinal {
    //上
    public  static  final String  UP = "UP";
    //下
    public  static  final String DOWN = "DOWN";
    //左
    public  static  final String LEFT = "LEFT";
    //右
    public  static final  String RIGHT = "RIGHT";
}

缺点:

  1. 得记住 “UP” ,“DOWN” 这些字符串
  2. 用equals 判断; “UP” .equals(GameStaticFinal.UP) "UP"写成了死代码,不灵活

二、枚举定义

2.1 创建枚举类

public enum  GameEnum {
    
    UP, //上
    DOWN, //下
    LEFT, //左
    RIGHT; //右
    
}

2.2 特点

java定义枚举类型key value 形式 java枚举的定义_枚举类_02

类用关键字Enum

特殊的常量类

用 javap GameEnum.class 查看一个汇编命令:

java定义枚举类型key value 形式 java枚举的定义_System_03

默认构造器是私有的

查看class

java定义枚举类型key value 形式 java枚举的定义_System_04

里边的常量相当于枚举对象

java定义枚举类型key value 形式 java枚举的定义_数据结构_05

符号, ;

用逗号分隔,用;结尾

命名规则

类名带Enum , 常量全部大写,多个单词有_分割

java定义枚举类型key value 形式 java枚举的定义_System_06

三、枚举的应用

3.1常量

可以把常量写入枚举,使用时直接 枚举类名.常量名 调用

3.2 可以应用到switch当中

//获取里边的常量
Test01Enum e = Test01Enum.UP;
switch (e) {
    case UP:
        break;
    case LEFT:
        break;
    case DOWN:
        break;
    case RIGHT:
        break;
    case SKIP:
        break;
    default:
        break;
}

3.3 有参数的枚举常量对象

java定义枚举类型key value 形式 java枚举的定义_枚举类_07

public enum Test03Enum {
    //四套:  success code msg 信息 整合的对象
    SELECT_SUCCESS(true,1001,"查询成功"),
    DELETE_SUCCESS(true,1002,"删除成功"),
    UPDATE_ERROR(false,1003,"更新失败"),
    ADD_ERROR(false,1004,"添加失败");
    //返回码: success  code  msg
    private  boolean success;
    private  int code;
    private  String msg;

    //构造器方法
    Test03Enum(boolean success, int code, String msg) {
        this.success = success;
        this.code = code;
        this.msg = msg;
    }

    public boolean isSuccess() {
        return success;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

}

测试:

public class Test03Main {
    public static void main(String[] args) {
        //1.获取有参构造器的枚举对象
        Test03Enum e = Test03Enum.SELECT_SUCCESS;

        System.out.println(e.isSuccess());
        System.out.println(e.getCode());
        System.out.println(e.getMsg());
    }
}

3.4 可以重写toString 方法

在3.3基础上添加代码

@Override
public String toString() {
    return this.success + " "+ this.code+" "+ this.msg;
}

3.5 枚举类可以实现接口

public interface Test05Interface {

    //输出
    public void sout();

}

实现:

public enum  Test05Enum implements  Test05Interface{
    UP
    ;
    @Override
    public void sout() {
        System.out.println("这个方法可以调到");
    }
}

3.6 在接口中:枚举类

public interface Test06Interface {

    //1.可以在接口中定义枚举
    enum  Test06Enum implements Test06Interface {
        UP,DOWN;
    }

}
public class Test06Main {

    public static void main(String[] args) {
        
        Test06Interface  e  = Test06Interface.Test06Enum.DOWN;
        System.out.println(e);

    }
}

3.7 枚举可用放到集合当中

public enum  Test07Enum {

    DOWN,UP,LEFT,SKIP,RIGHT;
}
public class Test07Main {

    public static void main(String[] args) {

        //1.创建一个泛型是枚举的集合
        List<Test07Enum>  list = new ArrayList<>();

        //2. 添加元素
        list.add(Test07Enum.UP);
        list.add(Test07Enum.UP);
        list.add(Test07Enum.DOWN);

        for (Test07Enum test07Enum : list) {
            System.out.println(test07Enum);
        }

        System.out.println("=======================================");
        //set 当中的元素是不重复的,所以,我可以去重
        // 利用 EnumSet可以去重
        EnumSet<Test07Enum> test07Enums = EnumSet.copyOf(list);
        System.out.println(test07Enums);

        System.out.println("=================================");
        // 利用 EnumSet  可以返回一个 EnumSet类型的集合 : 范围: 区间
        EnumSet<Test07Enum> range = EnumSet.range(Test07Enum.UP, Test07Enum.SKIP);
        System.out.println(range);


        System.out.println("EnumMap==========================");
        //EnumMap: key是枚举 类型  : 参数是枚举 的class类型

        EnumMap<Test07Enum,String>  map = new EnumMap<>(Test07Enum.class);
        map.put(Test07Enum.UP,"上");
        map.put(Test07Enum.DOWN,"下");

        String s = map.get(Test07Enum.UP);
        System.out.println(s);
        //EnumMap 数组结构 : 专门为 枚举 类型设计的map结构
    }

}

四、父类java.lang.Enum

ctrl +H 可以查看你定义的枚举类的父类 是 Enum

Java 中的每一个枚举都继承自 java.lang.Enum 类。

当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 final、public, static 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。

java定义枚举类型key value 形式 java枚举的定义_数据结构_08

继承方法

java定义枚举类型key value 形式 java枚举的定义_System_09

常见方法:

values()

以数组形式返回枚举类型的所有成员

valueOf()

将普通字符串转换为枚举实例

compareTo()

比较两个枚举成员在定义时的顺序

ordinal()

获取枚举成员的索引位置

public enum Test08Enum {

    DOWN,UP,LEFT,SKIP,RIGHT;


}
//1. values : 以数组形式返回枚举类型的所有成员
Test08Enum[] values = Test08Enum.values();
System.out.println(Arrays.toString(values));
//2. valueOf 将普通字符串转换为枚举实例
Test08Enum up = Test08Enum.valueOf("UP");
System.out.println(up);
//3.比较定义的顺序
Test08Enum down = Test08Enum.DOWN;
Test08Enum skip = Test08Enum.SKIP;
int before = down.compareTo(skip);
int after = skip.compareTo(down);
int equ = down.compareTo(down);

System.out.println(before);  //-3 左倒第3个
System.out.println(after);//3  右第3个
System.out.println(equ); //0
//4. ordinal: 索引
int ordinal = down.ordinal();
System.out.println(ordinal);

五、枚举为什么是线程安全的?

javap xxx.class

java定义枚举类型key value 形式 java枚举的定义_System_10


枚举类最终会被编译为被 final 修饰的普通类

常量是用static final 修饰

枚举类在项目启动时就会被 JVM 加载并初始化,而这个执行过程是线程安全的,所以枚举类也是线程安全的类。