2021 年 10 月 11 日,最近有点忙 … 说好要好好学习😥 每天 10 点学习两小时的我又:咕咕了🕊…
自己学习次要来源于 尚硅谷
集体源码地址
- 借鉴文章
Java 枚举
枚举 enum
什么是枚举类:
Java 枚举是一个非凡的类,个别示意一组常量
- 比方: 一年的 4 个节令,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等 …
- 相似这种当一个变量有几种固定可能的取值时, 能够将它定义为枚举类型
呈现:
- Java1.5 之前是没有
枚举
和注解
的. - 那时候个别用接口常量来代替
而应用 Java 枚举类型 enum 能够更贴近地示意这种常量.
还能够配合 Switch 应用 …
枚举类的实现:
- JDK1.5 之前须要自定义枚举类.
- JDK 1.5 新增的
enum
关键字用于定义枚举类. - 若枚举只有一个对象, 则能够作为一种单例模式的实现形式.
1.5 之前 自定义实现枚举类:
- 私有化类的结构器,保障不能在类的内部创立其对象
- 在类的外部创立枚举类的实例,申明为:
public static final
确保对象不会更改~ - 对象如果有实例变量,应该申明为:
private final
通过结构器初始化
SeasonTest1.Java
Season.Java
package com.wsm;
/**
* 自定义枚举类学习 Season 节令: 一年有四个节令是固定是刚好用来做枚举类
*/
public class SeasonTest1 {public static void main(String[] args) {
// 春天
Season chu = Season.SPRING;
System.out.println(chu.toString());
/**
* ok, 这就是自定义枚举类, 类的对象是有固定个数的!且不可更改, 救像一种规定固定的对象...
* 罕用于规定状态的定义: 商品: 缺货 代发货 待付款... 等固定的状态;
* */
}
}
class Season{
//1. 私有化类的结构器, 并给对象属性赋值: 如果有对象属性的话顺便给属性赋值~
private Season(String seasonName,String seasonDesc){
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
//2. 申明 Season 对象的属性:private final 润饰, 因为枚举对象是固定的不能更改的.
private final String seasonName;
private final String 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("冬天","冰天雪地");
//ok, 到这儿, 自定义的枚举类就创立好了
// 如果还有其它需要能够进行扩大... 创立办法:
/** 获取枚举类对象的属性 */
/** 常量只有 get(); 办法 */
public String getSeasonName() {return seasonName;}
public String getSeasonDesc() {return seasonDesc;}
/** toString()办法 */
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
}
- JDK5 之前, 的枚举类须要通过改办法进行自定义~
Java 中被 Final 润饰的变量的几种赋值形式
- Final 示意 ” 最初的、最终的 ” 含意,变量一旦赋值后,不能被从新赋值
- 被 Final 润饰的实例变量必须显式指定初始值
- Final 修饰符通常和 static 修饰符一起应用来创立类常量
非动态 Final 赋值有三种:定义初始化、非动态代码块、构造方法
/* 定义初始化时进行赋值
在申明对象时间接赋值,赋值后就不可变了,这种是最容易想到的
*/
public class FinalTest {private final Integer num = 10;}
/* 代码块中赋值
这种是在定义之初不进行赋值操作,而是在代码块中进行赋值,也是能够的
结构块会在创建对象时被调用, 每次创立时都会被调用, 优先于类构造函数执行.
*/
public class FinalTest {
private final Integer num;
{num = 10;}
}
/*
结构器中赋值
在创建对象时进行赋值, 一旦对象创立实现, 就不可变了, 所以在创立完对象后 set()办法是不能进行赋值的
*/
public class FinalTest {
private final Integer num;
public FinalTest(Integer num) {this.num = num;}
}
动态应用 Final: static final
- static final 赋值有两种: 定义初始化、动态代码块
/* 定义初始化 */
public class FinalTest {private static final Integer num = 10 ;}
/* 动态代码块
用 static{}包裹起来的代码片段,只会执行一次 动态代码块优先于结构块执行.
*/
public class FinalTest {
private static final Integer num;
static {num = 10;}
}
enum 关键字实现枚举类:
- enum 定义的枚举类默认继承了
Java.lang.Enum
类:因而不能再 extends 继承其余类
但能够 implements - 枚举类的结构器只能应用 private 权限修饰符
必须在枚举类的第一行申明枚举类对象
JDK 1.5 中能够在 switch 表达式中应用 Enum 定义的枚举类的对象 作为表达式
case 子句能够间接应用枚举值的名字(无需增加枚举类作为限定)
SeasonTest2.Java
Season.Java
package com.wsm.two;
import javax.sound.midi.Soundbank;
/***
* JDK1.5 新增 enum
*/
public class SeasonTest2 {public static void main(String[] args) {
/** 秋天 */
Season AUTUMN = Season.AUTUMN;
System.out.println(AUTUMN); // 尝试正文 toString()办法输入: AUTUMN (对象名)
//enum extends Java.lang.enum 类
/** enum 罕用办法 */
//values()办法:// 返回枚举类型的对象数组。该办法能够很不便地遍历所有的枚举值
//valueOf(String str)
// 能够把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异样:IllegalArgumentException。//toString() 返回以后枚举类对象常量的名称
/** values() */
System.out.println("enum 罕用办法 values()");
Season[] values = Season.values(); // 返回该 enum 的所有对象
// 遍历后果集
for (Season value : values) {System.out.println(value);
}
/** valueOf(String str) */
System.out.println("enum 罕用办法 valueOf(String str)");
Season winter = Season.valueOf("WINTER"); // 依据固定对象名, 返回对应的 enum
System.out.println(winter);
/** switch 用法
* 判断对象属于那一个...
* */
System.out.println("enum switch 用法");
switch (winter){
case SPRING:
System.out.println("春");
break;
case SUMMER:
System.out.println("夏");
break;
case AUTUMN:
System.out.println("秋");
break;
case WINTER:
System.out.println("冬");
break;
default:
System.out.println("没有匹配!");
}
}
}
/** 能够于自定义枚举进行比拟查看~ */
enum Season{
//1. 必须在枚举类的第一行申明枚举类对象
// 枚举类的所有实例必须在枚举类中显式列出(, 分隔 ; 结尾)
// 因为枚举, 本机不可批改由类拜访能够勾销: public static final 类
// public static final Season SPRING = new Season("春天","春暖花开");
SPRING("春天","春暖花开"),
SUMMER("夏天","夏日炎炎"),
AUTUMN("秋天","秋高气爽"),
WINTER("冬天","冰天雪地");
//2. 申明 Season 对象的属性:private final 润饰
private final String seasonName;
private final String seasonDesc;
//3. 私有化类的结构器, 并给对象属性赋值
private Season(String seasonName,String seasonDesc){
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
// 扩大办法
/** get */
public String getSeasonName() {return seasonName;}
public String getSeasonDesc() {return seasonDesc;}
/** toString
* 正文办法间接输入发现, 即便不从新 toString(); 也不是打印对象的: 地址值(栈指向堆的地址!)
* 因为: enum 类, 是继承于 Java.lang.enum 的, 而不是 Object 类
* */
// @Override
// public String toString() {
// return "Season{" +
// "seasonName='" + seasonName + '\'' +
// ", seasonDesc='" + seasonDesc + '\'' +
// '}';
// }
}
enum 罕用办法
办法名称 | 形容 |
---|---|
values() | 以数组模式返回枚举类型的所有成员 |
valueOf(String) | 将一般字符串转换为枚举实例 |
compareTo() | 比拟两个枚举成员在定义时的程序 |
ordinal() | 获取枚举成员的索引地位 |
enum 高级:implements 实现类
- enum 类继承了
java.lang.enum 类
Java 单根性所以不能在继承, 但 Java 能够多实现
eunm 类 还能够 实现接口... 达到扩大的形式
实现形式:
-
失常实现,重写办法 ….
但这样所有的对象, 办法实现都一样!
SeasonTest3
Season
Info
public class SeasonTest3 {public static void main(String[] args) { Season autumn = Season.AUTUMN; autumn.show();} } // 应用 enum 关键字枚举类 implements 实现接口, 重写 show()办法~ enum Season implements Info{SPRING("春天","春暖花开"), SUMMER("夏天","夏日炎炎"), AUTUMN("秋天","秋高气爽"), WINTER("冬天","冰天雪地"); //2. 申明 Season 对象的属性:private final 润饰 private final String seasonName; private final String seasonDesc; //3. 私有化类的结构器, 并给对象属性赋值 private Season(String seasonName,String seasonDesc){ this.seasonName = seasonName; this.seasonDesc = seasonDesc; } // 重写接口的办法!@Override public void show() {System.out.println("这是一个节令~"); } } /** 接口 */ interface Info{void show(); }
-
给每个 enum 对象,来一个特有的固定实现!
public class SeasonTest4 {public static void main(String[] args) { Season autumn = Season.AUTUMN; autumn.show();} } // 应用 enum 关键字枚举类 implements 实现接口, 重写 show()办法~ enum Season implements Info {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("大概在夏季"); } }; //2. 申明 Season 对象的属性:private final 润饰 private final String seasonName; private final String seasonDesc; //3. 私有化类的结构器, 并给对象属性赋值 private Season(String seasonName,String seasonDesc){ this.seasonName = seasonName; this.seasonDesc = seasonDesc; } } /** 接口 */ interface Info{void show(); }
枚举汇合
在 Java 语言中和枚举类相干的,还有两个枚举汇合类 java.util.EnumSet
和 java.util.EnumMap
应用 EnumSet
能够保障元素不反复,并且能获取指定范畴内的元素
public class EnumTest {public static void main(String[] args) {List<ErrorCodeEnum> list = new ArrayList<ErrorCodeEnum>();
list.add(ErrorCodeEnum.SUCCESS);
list.add(ErrorCodeEnum.SUCCESS); // 反复元素
list.add(ErrorCodeEnum.SYS_ERROR);
list.add(ErrorCodeEnum.NAMESPACE_NOT_FOUND);
// 去掉反复数据
EnumSet<ErrorCodeEnum> enumSet = EnumSet.copyOf(list);
System.out.println("去重:" + enumSet);
// 获取指定范畴的枚举(获取所有的失败状态)EnumSet<ErrorCodeEnum> errorCodeEnums = EnumSet.range(ErrorCodeEnum.ERROR, ErrorCodeEnum.UNKNOWN_ERROR);
System.out.println("所有失败状态:" + errorCodeEnums);
}
}
enum ErrorCodeEnum {SUCCESS(1000, "success"),
ERROR(2001, "parameter error"),
SYS_ERROR(2002, "system error"),
NAMESPACE_NOT_FOUND(2003, "namespace not found"),
NODE_NOT_EXIST(3002, "node not exist"),
NODE_ALREADY_EXIST(3003, "node already exist"),
UNKNOWN_ERROR(9999, "unknown error");
private int code;
private String msg;
ErrorCodeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int code() { return code;}
public String msg() { return msg;}
}
EnumMap
与HashMap
相似,不过它是一个专门为枚举设计的Map
汇合-
相比
HashMap
来说它的性能更高,因为它外部放弃应用链表和红黑树的构造,采纳数组作为数据存储的构造-
以枚举作为 key,查问间接找到对应的
数组下标
疾速定位元素EnumMap< 枚举对象,Object>
-
为什么应用枚举?😕
更强的 类型束缚
- 在枚举没有诞生之前,也就是 JDK 1.5 版本之前
-
咱们通常会应用
int
常量来示意枚举,用来辨别,状态类型: B 站上传视频为例,视频个别有三个状态:草稿 、 审核 和公布int
类型自身并不具备安全性 ,如果某个程序员在定义int
时少些了一个final
关键字,那么就会存在被其他人批改的危险,反观枚举类,它“人造”就是一个常量类,不存在被批改的危险。
应用
int
类型的语义不够明确枚举更加清晰示意一种状态
单例模式:
- 应用枚举实现
单例模式
更加简略!
线程平安:
- 枚举类最终会被编译为被
final
润饰的一般类 - 它的所有属性也都会被
static
和final
关键字润饰,所以枚举类在我的项目启动时就会被 JVM 加载并初始化且不容许更改!线程平安
不便比拟:
- 枚举比拟时应用 == 就够了,因为枚举类是在程序加载时就创立了(它并不是
new
进去的)每个对象全局只有一个!
- == 比拟地址,雷同对象的地址也雷同!
ok, 枚举就介绍到这儿了,晚安,集美门😘