网站首页 > 精选教程 正文
引出枚举
首先来考虑这样一个需求:判断一个员工(Employee)在一周的哪一天休息。
解决方案:定义一个类Weekday来表示周1到周日,在类中分别使用7个常量来表示周1到周日,代码如下:
public class Employee {
// 休息日
private int restDay;
public void setRestDay(int restDay) {
this.restDay = restDay;
}
public int getRestDay() {
return restDay;
}
public void isRestDay() {
if (restDay == 6 || restDay == 7) {
System.out.println("今天是休息日");
} else {
System.out.println("今天不是休息日");
}
}
}
public class WeekDay {
public static final int MONDAY = 1;
public static final int TUESDAY = 2;
public static final int WEDNESDAY = 3;
public static final int THURSDAY = 4;
public static final int FRIDAY = 5;
public static final int SATURDAY = 6;
public static final int SUNDAY = 7;
}
运行案例:
public static void main(String[] args) {
Employee employee = new Employee();
employee.setRestDay(WeekDay.SUNDAY);
employee.isRestDay();
}
此时,上述的代码示例很清楚的解决了业务需求,引入的Weekday类很好的表示了从周一到周日。但是也存在一些问题,因为在Employee中的restDay的类型是int类型,我们依然可以随意设置irestDay的值,代码并不健壮,依然没有解决数据类型不安全的问题,任然有改进的空间。
为了解决数据类型不安全的问题的问题,可以在WeekDay中引入私有构造器,防止WeekDay被除自身以外的其他对象实例化,然后可以将WeekDay作为休息日的数据类型,很好的解决了数据类型不安全的问题,同时,也可以将休息日的个数固定下来。改造后的代码如下:
public class Employee {
// 休息日
private WeekDay restDay;
public void setRestDay(WeekDay restDay) {
this.restDay = restDay;
}
public WeekDay getRestDay() {
return restDay;
}
public void isRestDay() {
if (restDay == WeekDay.SATURDAY || restDay == WeekDay.SUNDAY) {
System.out.println("今天是休息日");
} else {
System.out.println("今天不是休息日");
}
}
}
public class WeekDay {
private WeekDay() {}
public static final WeekDay MONDAY = new WeekDay();
public static final WeekDay TUESDAY = new WeekDay();
public static final WeekDay WEDNESDAY = new WeekDay();
public static final WeekDay THURSDAY = new WeekDay();
public static final WeekDay FRIDAY = new WeekDay();
public static final WeekDay SATURDAY = new WeekDay();
public static final WeekDay SUNDAY = new WeekDay();
}
运行案例:
public static void main(String[] args) {
Employee employee = new Employee();
employee.setRestDay(WeekDay.SUNDAY);
employee.isRestDay();
}
到这里,不仅业务需求明确,数据类型安全的问题也解决了。
Java 枚举
从Java 5 开始,提供了一种新的数据类型,枚举。和接口一样,枚举是一个特殊的类,其实质上就是数量固定的多个常量对象的集合。枚举主要用来表示固定的事务类型。
枚举语法定义格式:常量之间使用英文状态下的“,”分隔,最后一个常量之后必须要用“;”结尾。
[修饰符] enum 枚举类名
{
常量A,常量B,常量C;
}
在上述案例中的WeekDay类用枚举来重写就是这样的:
enum WeekDay {
MONDAY,TUESDAY,WEDNESDAY,THURSDAY ,FRIDAY,SATURDAY,SUNDAY;
}
在开发中自定义的枚举类,在底层都是直接继承于java.lang.Enum类的,Enum类是所有枚举的父类。看下图会有一个更直观的感受:
枚举特点:
- 枚举的直接父类是java.lang.Enum,但和java.lang.Object一样,枚举都不会显式地继承Enum。
- 枚举就相当于一个类,可以定义构造方法、成员变量、普通方法和抽象方法。
- 拥有默认的私有构造方法,即使不写访问权限也是private,因为枚举在底层没有无参数构造器的。
- 枚举中的每个常量都是全局的,每个常量都是一个实例,且因为常量个数是固定的有限个的,所以实例个数也是固定的,且枚举类不能使用new关键字。
- 枚举实例必须位于枚举结构体中的最开始部分,枚举实例列表的最后必须要有分号与其他成员相分隔。
- 枚举实例后有花括号时,该实例是枚举类的匿名内部类对象。
枚举的使用:
1.枚举中的常量都是全局公共的静态常量,可以直接使用枚举类名调用。
Weekday day = Weekday.SATURDAY;
2.因为java.lang.Enum类是所有枚举类的父类,所以所有的枚举对象可以调用Enum类中的方法。
String name = 枚举对象.name(); // 返回枚举对象的常量名称
int ordinal = 枚举对象.ordinal(); // 返回枚举对象的序号,从0开始.
String str = 枚举对象.toString(); // 返回 枚举对象的常量名称
3.JVM为枚举类生成的静态方法:
1.枚举类型[] values();
Weekday[] ws = Weekday.values();:返回当前枚举类型所有的常量,使用一个数组封装起来.
2.枚举类型 valueof(String name);
Weekday day = Weekday.valueOf("MONDAY"); // 把一个指定名称字符串转换为当前枚举类中同名的常量.
4.从Java 5开始switch也支持操作枚举类型。Java switch的使用细节和使用注意
虽然switch只支持int类型,但因为支持枚举时在底层使用的枚举常量的ordinal,而ordinal的类型依然是int类型。所以也可以说switch是在间接支持枚举。
枚举的单例模式
在<<effective java>>书中提到,建议使用枚举类做单例模式,能够很好的保护代码隐私,即使使用反射也不能创建对象。通过以下的两种代码对比,能够很直观的展现枚举实现的单例模式:
完结。
猜你喜欢
- 2024-11-09 Java基础入门要学哪些 怎么掌握反射和枚举
- 2024-11-09 谈谈枚举的新用法--java java枚举类型有什么用
- 2024-11-09 Java面试基础回顾16-枚举 java面试基础知识点
- 2024-11-09 实际工作中推荐使用java枚举类型,提高开发效率#编程
- 2024-11-09 java枚举enumeration java枚举根据value获取key
- 2024-11-09 大年初二来简单聊聊java中枚举类的前世今生
- 2024-11-09 如何用枚举消除if/else?-枚举高阶用法
- 2024-11-09 干货 | 一文搞定Python 枚举 python 枚举遍历
- 2024-11-09 Scala学习九之枚举和Trait了解 枚举compareto
- 2024-11-09 java中的enum第一期:enum存在的意义
你 发表评论:
欢迎- 04-11Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- 04-11Java中你知道几种从字符串中找指定的字符的数量
- 04-11探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- 04-11Python字符串详解与示例(python字符串的常见操作)
- 04-11java正则-取出指定字符串之间的内容
- 04-11String s1 = new String("abc");这句话创建了几个字符串对象?
- 04-11java判断字符串中是否包含某个字符
- 04-11关于java开发中正确的发牌逻辑编写规范
- 最近发表
-
- Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- Java中你知道几种从字符串中找指定的字符的数量
- 探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- Python字符串详解与示例(python字符串的常见操作)
- java正则-取出指定字符串之间的内容
- String s1 = new String("abc");这句话创建了几个字符串对象?
- java判断字符串中是否包含某个字符
- 关于java开发中正确的发牌逻辑编写规范
- windows、linux如何后台运行jar(并且显示进程名)
- 腾讯大佬私人收藏,GitHub上最受欢迎的100个JAVA库,值得学习
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)