JavaSE进阶--枚举

一、介绍

1、概念

枚举是一种数据类型,用于定义一组命名的常量。枚举常量通常表示一组相关的值,例如颜色、方向、状态等。通过使用枚举,我们可以将一组相关的常量组织在一起,使代码更加清晰和可读。在许多编程语言中,枚举常量可以通过名称来引用,而不是使用具体的数值。这使得代码更易于理解和维护。

2、使用场景

在Java中,类的对象是有限个,确定的,也就是有限个固定值,这个类我们就可以定义为枚举类,如下:

性别:男女
月份:1,2…12
星期:一、二…日

3、好处

  • 提高代码的可读性的可维护性,比如一个int类型,直接设置为1,根据就不知道什么意思,一头雾水,使用枚举,命名好,不用看注释就能知道什么意思
  • 解耦,好扩展,常量值变动,直接改对应枚举值就行

4、特点

  • 任意两个枚举成员不能具有相同的名称
  • 多个枚举成员之间使用逗号分隔,最后一个成员用分号
  • 枚举类型成员都可以看作是 Enum 类的实例,被public static final修饰
  • 构造器默认使⽤private修饰
  • 一般禁止写set方法,因为基本是只读的,写上也不会报错

二、如何自定义枚举

1、 JDK1.5之前的写法

通过类常量来实现,代码如下:

public class ProgrammingLanguage {
	private final Integer id;
	private final String desc;

	private ProgrammingLanguage(Integer id, String desc) {
		this.id = id;
		this.desc = desc;
	}

	public static final ProgrammingLanguage JAVA = new ProgrammingLanguage(1, "java");
	public static final ProgrammingLanguage PYTHON = new ProgrammingLanguage(2, "python");
	public static final ProgrammingLanguage GOLANG = new ProgrammingLanguage(3, "go");
	public static final ProgrammingLanguage C = new ProgrammingLanguage(4, "c");
	public static final ProgrammingLanguage PHP = new ProgrammingLanguage(5, "php");

	public Integer getId() {
		return id;
	}

	public String getDesc() {
		return desc;
	}

}

2、 JDK1.5开始的写法

通过 enum 关键字声明枚举,代码如下:

public enum ProgrammingLanguageEnum {

	JAVA(1, "java"),
	PYTHON(2, "python"),
	GOLANG(3, "go"),
	C(4, "c"),
	PHP(5, "php");

	private Integer id;
	private String desc;

	ProgrammingLanguageEnum(Integer id, String desc) {
		this.id = id;
		this.desc = desc;
	}

	public Integer getId() {
		return id;
	}

	public String getDesc() {
		return desc;
	}

}

可以简写,没有显式地声明属性的话,构造器,方法都可以省略不写

public enum SexEnum {
	MAN,
	WOMAN;
}

3、 两种方式区别

  • 使用 enum 关键字声明枚举类的上层父类 :java.lang.Enum
  • 使用类常量实现枚举类的上层父类:java.lang.Object

三、常用方法

  • name():返回枚举常量的名称
  • ordinal():返回枚举常量的序号(它在枚举声明中的位置,其中初始常量被分配为零序数)
  • toString():返回枚举常量的名称
  • values():返回枚举类对象的数组
  • valueOf():通过对象名字获取这个枚举对象,对象的名字必须传正确,区分大小写,否则抛出异常

1、返回常量信息

ProgrammingLanguageEnum programmingLanguage = ProgrammingLanguageEnum.JAVA;
System.out.println(programmingLanguage.name()); // JAVA
System.out.println(programmingLanguage.ordinal()); // 0
System.out.println(programmingLanguage); // JAVA

2、返回枚举对象的数组

ProgrammingLanguageEnum[] values = ProgrammingLanguageEnum.values();
for (ProgrammingLanguageEnum value : values) {
	System.out.println(value);
}

输出结果如下:

JAVA
PYTHON
GOLANG
C
PHP

3、通过对象名字获取这个枚举对象

对象的名字必须传正确,区分大小写,否则抛出异常

ProgrammingLanguageEnum programmingLanguage = ProgrammingLanguageEnum.valueOf("JAVA");
System.out.println(programmingLanguage); // JAVA

4、关于name和toString的疑惑,两者好像都是返回一样的?那应该使用哪个?

两者都是用于获取枚举常量的字符串表示,大多数程序员应该优先使用 toString 方法,因为 toString 方法可能会返回更用户友好的名称,此方法主要用于正确性取决于获取确切名称的特殊情况,该名称不会因版本而异。

四、应用场景

1、实现接口,调用不同方法

定义一个接口,统一枚举方法,枚举类实现该接口,通过实现不同对象调用不同方法

public enum ProgrammingLanguage implements Forlan{

	JAVA(1, "java"){
		@Override
		public void print() {
			System.out.println("Forlan,这是java");
		}
	},
	PYTHON(2, "python"){
		@Override
		public void print() {
			System.out.println("Forlan,这是python");
		}
	},
	GOLANG(3, "go"){
		@Override
		public void print() {
			System.out.println("Forlan,这是go");
		}
	},
	C(4, "c"){
		@Override
		public void print() {
			System.out.println("Forlan,这是c");
		}
	},
	PHP(5, "php"){
		@Override
		public void print() {
			System.out.println("Forlan,这是php");
		}
	};
	...

2、通过属性值找到对应的属性值

使用增强get方法,遍历枚举找到对应的属性值

public static Integer getId(String desc) {
	for (ProgrammingLanguageEnum vlaue : values()) {
		if (vlaue.desc.equals(desc)) {
			return vlaue.getId();
		}
	}
	return null;
}
public static String getDesc(Integer id) {
	for (ProgrammingLanguageEnum value : values()) {
		if (value.getId().equals(id)) {
			return value.getDesc();
		}
	}
	return "未知";
}

3、实现设计模式

3.1 单例

在单例中,可以使用枚举值,作为参数,例如:

ProgrammingLanguage programmingLanguage = ProgrammingLanguage.JAVA;

3.2 责任链

public enum FilterTypeEnum {
	BEFORE {
		@Override
		public FilterTypeEnum doFilter() {
			System.out.println("执行前过滤");
			return AROUND;
		}
	},
	AROUND {
		@Override
		public FilterTypeEnum doFilter() {
			System.out.println("执行中过滤");
			return AFTER;
		}
	},
	AFTER {
		@Override
		public FilterTypeEnum doFilter() {
			System.out.println("执行后过滤");
			return null;
		}
	};

	public abstract FilterTypeEnum doFilter();

	public static void main(String[] args) {
		FilterTypeEnum filterTypeEnum = FilterTypeEnum.BEFORE;
		while (filterTypeEnum != null) {
			filterTypeEnum = filterTypeEnum.doFilter();
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员Forlan

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值