目录
一、 为什么要命名用枚举
1.1需求:
玩游戏有上下左右 ,请创建一个类,定义上下左右四个常量
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;
}
缺点:
-
必须要写static final 这两个关键字不能忘记!
-
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";
}
缺点:
-
得记住 “UP” ,“DOWN” 这些字符串
-
用equals 判断; “UP” .equals(GameStaticFinal.UP) "UP"写成了死代码,不灵活
二、枚举定义
2.1 创建枚举类
public enum GameEnum {
UP, //上
DOWN, //下
LEFT, //左
RIGHT; //右
}
2.2 特点
类用关键字Enum
特殊的常量类
用 javap GameEnum.class 查看一个汇编命令:
默认构造器是私有的
查看class
里边的常量相当于枚举对象
符号, ;
用逗号分隔,用;结尾
命名规则
类名带Enum , 常量全部大写,多个单词有_分割
三、枚举的应用
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 有参数的枚举常量对象
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 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。
继承方法
常见方法:
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
枚举类最终会被编译为被 final
修饰的普通类
常量是用static final 修饰
枚举类在项目启动时就会被 JVM 加载并初始化,而这个执行过程是线程安全的,所以枚举类也是线程安全的类。