个人推荐:
📢📢📢 前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下
"通俗易懂,风趣幽默"
,感觉非常有意思,忍不住分享一下给大家。
点击跳转到教程。
前言
最近在回顾JavaSE部分的知识,对一些薄弱的知识进行记录,学习方式,通过视频和图书的进行学习,视频看B站韩顺平老师的30天学会Java,图书看Java核心技术 卷I 基础知识(原书第10版)。
韩顺平30天学会Java地址:https://www.bilibili.com/video/BV1fh411y7R8?p=425
一.枚举的简介
1.枚举的引出(自定义枚举)
需求:创建一个季节对象(Season),该对象包含季节名称和描述
package com.dudu.enumerone;
public class Season {
private String name;
private String desc;
public Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
class Test{
public static void main(String[] args) {
Season spring = new Season("春天","温暖");
Season winter = new Season("冬天", "寒冷");
Season summer = new Season("夏天", "炎热");
Season autumn = new Season("秋天", "凉爽");
}
}
上面的代码是可以完成我们的需求,但是我们可以知道,季节对象是固定的(春夏秋冬),不会出现其他季节了,如果我们再增加一个Season对象,这时候就会打破这种固定的季节,显然这种方式并不完美!
进一步完善
分析Season对象的特点:
- 季节的值是有限的几个值(spring,summer,autumn,winter)
- 只读,不需要修改
根据上面的特点设计如下代码:
package com.dudu.enumerone;
public class Season {
private String name;
private String desc;
public static final Season SPRING = new Season("春天","温暖");
public static final Season WINTER = new Season("冬天", "寒冷");
public static final Season SUMMER = new Season("夏天", "炎热");
public static final Season AUTUMN = new Season("秋天", "凉爽");
private Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
public void setName(String name) {
this.name = name;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
class Test{
public static void main(String[] args) {
System.out.println("季节:"+Season.SPRING.getName()+"描述:"+Season.SPRING.getDesc());
System.out.println("季节:"+Season.WINTER.getName()+"描述:"+Season.WINTER.getDesc());
System.out.println("季节:"+Season.SUMMER.getName()+"描述:"+Season.SUMMER.getDesc());
System.out.println("季节:"+Season.AUTUMN.getName()+"描述:"+Season.AUTUMN.getDesc());
}
}
运行效果:
注意:
(这里的不可修改表示的是无法改为指向其他对象,但其指向的对象本身是可以被修改的。
)
final修饰的引用对象无法指向其他对象:
对象本身可以修改:
运行效果:
2.使用enum关键字
枚举(enumeration,简写enum),是一组常量集合,属于一种特殊的类,里面只包含一组有限的特定的对象。
在上面的代码中,Season类里面无非就是包含四组常量对象(spring,summer,autumn,winter),这非常符合枚举的定义,我们可以使用enum关键字来实现。
package com.dudu.enumerone;
public enum SeasonEnum {
SPRING("春天","温暖"),
SUMMER("夏天","炎热"),
AUTUMN("秋天","凉爽"),
WINTER("冬天","寒冷")
;
private SeasonEnum(String name, String desc) {
this.name = name;
this.desc = desc;
}
private String name;
private String desc;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
class Test_Enum{
public static void main(String[] args) {
System.out.println("季节:"+SeasonEnum.SPRING.getName()+"描述:"+SeasonEnum.SPRING.getDesc());
System.out.println("季节:"+SeasonEnum.WINTER.getName()+"描述:"+SeasonEnum.WINTER.getDesc());
System.out.println("季节:"+SeasonEnum.SUMMER.getName()+"描述:"+SeasonEnum.SUMMER.getDesc());
System.out.println("季节:"+SeasonEnum.AUTUMN.getName()+"描述:"+SeasonEnum.AUTUMN.getDesc());
}
}
运行效果:
我们会发现SeasonEnum(使用enum关键字)和上面设计的Season类非常相识,只有二处不同:
- Season使用的是Class关键字是一个类,而SeasonEnum使用的是enum关键字
- SeasonEnum中的常量对象类似于Season的简写方式
其实Season类这种方式也是实现枚举的一种方式,即自定义枚举类型。
Season类反编译原码:
SeasonEnum反编译源码(enum关键字本质上还是一个类(class),只是该类会继承Enum抽象类
):
3.注意事项(enum关键字实现枚举)
- 当我们使用enum关键字开发一个枚举类时,默认会继承Enum类,而且是一个final类
- 传统的(
public static final Season SPRING = new Season("春天","温暖");
)这种方式简化成SPRING("春天","温暖"),
,这里必须知道,它调用的是那个构造器 - 如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略
- 当有多个枚举对象时,使用
,
间隔,最后有一个分号结尾;
- 枚举对象必须放在枚举的行首
如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略:
枚举对象必须放在枚举的行首:
二.枚举的使用
需求,使用无参构造器,创建一个颜色(Color)枚举,包含三个常量(RED,GREEN,YELLOW)
代码如下:
package com.dudu.enumerone;
public enum Color {
RED,
GREEN,
YELLOW
;
}
class Test_ColorEnum{
public static void main(String[] args) {
Color color = Color.RED;
Color color1 = Color.RED;
System.out.println(color);
System.out.println(color == color1);
}
}
运行效果:
- 第一个输出
RED
是Color通过调用父类Enum类的toString()方法返回的name(这里的name就是RED)
- 第二个输出返回
true
,这是因为RED是一个Static的静态常量,作用在类上(地址和值都相同),color和color1指向的是同一个地址
三.枚举常用方法
说明:使用关键字enum时,会隐式继承Enum类,这样我们就可以使用Enum类相关的方法。
package com.dudu.enumerone;
public class EnumMethod {
public static void main(String[] args) {
// name():返回枚举对象的名字
System.out.println(SeasonEnum.AUTUMN.name());
// ordinal():返回枚举对象的次序(从0开始编号)
System.out.println(SeasonEnum.AUTUMN.ordinal());
// values():返回定义的所有枚举对象
SeasonEnum[] seasonEnums = SeasonEnum.values();
for (SeasonEnum seasonEnum:seasonEnums){
System.out.println(seasonEnum);
}
// valueOf():将字符串转换成枚举对象,要求该字符串必须为已有的常量名,否则会报错
SeasonEnum seasonEnum = SeasonEnum.valueOf("SPRING");
System.out.println(seasonEnum.getName());
// compareTo():比较二个枚举常量,比较的是编号(前一个的编号减后一个的编号) self.ordinal - other.ordinal
System.out.println("SPRING的编号为"+SeasonEnum.SPRING.ordinal());
System.out.println("AUTUMN的编号为"+SeasonEnum.AUTUMN.ordinal());
System.out.println("SPRING的编号 - AUTUMN的编号为"+(SeasonEnum.SPRING.ordinal()-SeasonEnum.AUTUMN.ordinal()));
System.out.println("SPRING和AUTUMN比较的编号为"+SeasonEnum.SPRING.compareTo(SeasonEnum.AUTUMN));
}
}
运行效果:
四.枚举使用细节
- 使用enum关键字后,就不能再继承其它类,因为enum会隐式继承Enum,而Java是单继承机制。
- 枚举类和普通类一样,可以实现接口,如:
enum 类名 implements 接口1,接口2{}
使用enum关键字后,就不能再继承其它类:
枚举类和普通类一样,可以实现接口:
运行效果: