Java枚举的小知识点

Wesley13
• 阅读 1017

enum 是jdk1.5引入的,使用它可以创建枚举类型,就像使用class创建类一样。

enum关键字创建的枚举类型默认是java.lang.Enum(一个抽象类)的子类

用法1 常量

一般定义常量都是 public static final …,现在可以把相关常量都放在一个枚举类里,而且枚举比常量提供更多方法

  1. enum season{

  2. Spring,Summer,Autumn,Winter

  3. }

用法2 switch jdk1.6之前只支持int,char,enum类型,使用enum,提高代码可读性

  1. enum season{

  2. Spring,Summer,Autumn,Winter

  3. }

  4. public class SeasonEnum {

  5. public static void main(String [] args) {

  6. season current_season=season.Autumn;

  7. switch(current_season) {

  8. case Spring:System.out.println("当前季节是"+current_season+" 竹外桃花三两枝,春江水暖鸭先知");break;

  9. case Summer:System.out.println("当前季节是"+current_season+" 接天莲叶无穷碧,映日荷花别样红");break;

  10. case Autumn:System.out.println("当前季节是"+current_season+" 停车做外枫林晚,霜叶红于二月花");break;

  11. case Winter:System.out.println("当前季节是"+current_season+" 忽如一夜出风来,千树万树梨花开");break;

  12. }

  13. }

  14. }

用法3 向枚举类中添加新方法 如果打算自己定义方法,必须在enum实例序列最后添加一个分号,而且必须先定义enum实例。

用法4 覆盖枚举的方法

  1. public enum CarInfoEnum {

  2. dongfeng("东风",15.8),

  3. benchi("奔驰",25.0),

  4. yiqi("一汽",18.5),

  5. baoma("宝马",35.7),

  6. xuelai("雪莱",100.5),

  7. ;

  8. /**

  9. * enum的构造方法要么是private ,要么是默认(默认私有),prtected和public都不行

  10. * @param name

  11. * @param price

  12. */

  13. CarInfoEnum(String name,Double price) {

  14. this.name=name;

  15. this.price= price;

  16. }

  17. private String name;

  18. private Double price;

  19. public String getName() {

  20. return name;

  21. }

  22. public void setName(String name) {

  23. this.name = name;

  24. }

  25. public Double getPrice() {

  26. return price;

  27. }

  28. public void setPrice(Double price) {

  29. this.price = price;

  30. }

  31. @Override

  32. public String toString() {

  33. return "名称:"+this.getName()+" 价格:"+this.getPrice();

  34. }

  35. public static void main(String [] args) {

  36. //获取枚举对象

  37. CarInfoEnum carEnum =CarInfoEnum.valueOf("dongfeng");

  38. System.out.println(carEnum.toString());

  39. //枚举遍历 方法1 使用java8新特性 方法引用、lambda表达式、Stream流

  40. CarInfoEnum[] cars= CarInfoEnum.values();

  41. Stream.of(cars).forEach(System.out::println);

  42. //枚举遍历 方法2 增强for

  43. for(CarInfoEnum car :CarInfoEnum.values()) {

  44. System.out.println(car);

  45. }

  46. }

  47. }

用法5 实现接口 所有枚举都继承自java.lang.Enum类,java类单继承,接口多继承,枚举对象可以实现多个接口。

用法6 使用接口组织枚举

  1. /*@description 使用接口组织枚举 对一组数据分类,食物菜单分类而且希望这些菜单都属于food类型,如mainCourse主菜,fruit水果 drink 饮品

  2. *每种分类下有多种具体的菜式或食品,此时可以利用接口组织

  3. */

  4. public interface Food {

  5. enum mainCourse implements Food{

  6. RICE,NOODLES,DUMPLING,CHINKEN,BEEF;

  7. }

  8. enum fruit implements Food{

  9. BANANA,APPLE,ORANGE,PEAR;

  10. }

  11. enum drink implements Food{

  12. TEA, MILK,COFFEE,GREEN_TEA,RED_TEA;

  13. }

  14. }

  15. public class TypeOfFood {

  16. public static void main(String [] args) {

  17. Food food=mainCourse.BEEF;

  18. System.out.println(food);

  19. food=fruit.APPLE;

  20. food=drink.COFFEE;

  21. }

  22. }

用法7 单例模式 由于枚举的构造默认是私有的,而且编译器jvm不允许使用反射机制创建枚举实例,因此使用枚举创建单例是非常安全,但是占用内存较大

  1. public enum SingletonEnum {

  2. INSTANCE,

  3. ;

  4. private String name; //该单例拥有的属性定义

  5. public String getName() {

  6. return name;

  7. }

  8. public void setName(String name) {

  9. this.name=name;

  10. }

  11. }

源码分析理解为什么枚举可以创建单例模式

枚举单例,使用SingletonEnum.INSTANCE进行访问,避免调用getInstance方法,完全不用考虑序列化和反射的问题。枚举序列化由jvm保证,每一个枚举类型和定义的枚举变量在jvm中唯一,在枚举类型序列化和反序列化上,java做如下规定:在序列化时java仅仅是将枚举对象的那么属性输出到结果,反序列化则是通过Enum的valueOf方法来根据名字查找枚举对象。同时编译器是不允许任何对这种序列化机制的定制的,并禁用了redObject,readObjectNoData,writeObject等,从而保证枚举实例唯一性。看一下Enum类的valueOf方法

  1. public static <T extends Enum> T valueOf(Class enumType, String name) {

  2. //调用enumType(Class对象的引用)的enumConstantDirectory方法获取到一个Map集合,该集合存放key(枚举name为key)--à value(枚举实例变量为value)对

  3. T result = enumType.enumConstantDirectory().get(name);

  4. if (result != null)

  5. return result;

  6. if (name == null)

  7. throw new NullPointerException("Name is null");

  8. throw new IllegalArgumentException(

  9. "No enum constant " + enumType.getCanonicalName() + "." + name);

  10. }

我们看一下Class类的enumConstantDirecotry方法

  1. Map<String, T> enumConstantDirectory() {

  2. if (enumConstantDirectory == null) {

  3. //getEnumConstantsShared最终通过反射调用枚举类的values方法

  4. T[] universe = getEnumConstantsShared();

  5. if (universe == null)

  6. throw new IllegalArgumentException(

  7. getName() + " is not an enum type");

  8. Map<String, T> m = new HashMap<>(2 * universe.length);

  9. //map存放了当前enum类的所有没举实例变量,以name为key值

  10. for (T constant : universe)

  11. m.put(((Enum<?>)constant).name(), constant);

  12. enumConstantDirectory = m;

  13. }

  14. return enumConstantDirectory;

  15. }

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java枚举类型enum的使用
java枚举类型enum的使用最近跟同事讨论问题的时候,突然同事提到我们为什么java中定义的常量值不采用enmu枚举类型,而采用publicfinalstatic 类型来定义呢?以前我们都是采用这种方式定义的,很少采用enum定义,所以也都没有注意过,面对突入起来的问题,还真有点不太清楚为什么有这样的定义。既然不明白就抽
Wesley13 Wesley13
3年前
java枚举
https://www.cnblogs.com/hyl8218/p/5088287.html摘抄并自查语法(定义)创建枚举类型要使用enum关键字,隐含了所创建的类型都是java.lang.Enum类的子类。枚举类符合通用模式ClassEnum<EextendsEnum<E,而E表示枚举类型的名称。枚举类型的每一
Wesley13 Wesley13
3年前
java枚举类型
java枚举类型enum枚举类型是java5新增特性的一部分,是一种特殊的数据类型(既是一种类类型但是又比类类型多些特殊的约束)枚举定义的方式:publicenumDay{MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY}定义
Wesley13 Wesley13
3年前
java枚举类
使用enum声明,默认直接继承了java.lang.Enum类,而不是Object类;枚举类的对象是固定的,实例个数有限,不可以再new(),枚举对象后可以跟()。枚举元素必须位于枚举类体中的最开始部分,枚举元素后要有分号与其他成员分隔。枚举类的构造方法的权限修饰符默认是private;一旦枚举对象后面加上{},那么该对象实际是枚举匿名内部
Wesley13 Wesley13
3年前
Java枚举使用场景
用法一:常量Java代码 1publicenumColor{2RED,GREEN,BLANK,YELLOW3}用法二:switchJDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。Java
Wesley13 Wesley13
3年前
Java枚举类使用
用法一:常量在JDK1.5 之前,我们定义常量都是: publicstaticfianl.... 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。 publicenumColor{RED,GREEN,BLANK,YELLOW}用法二
Wesley13 Wesley13
3年前
Java分享笔记:自定义枚举类 & 使用enum关键字定义枚举类
  在JDK1.5之前没有enum关键字,如果想使用枚举类,程序员需要根据Java语言的规则自行设计。从JDK1.5开始,Java语言添加了enum关键字,可以通过该关键字方便地定义枚举类。这种枚举类有自己的程序编写规则,并且具有一些特殊方法。  下面是笔者分别针对自定义枚举类和enum枚举类的程序设计。\1\自定义枚举类
小万哥 小万哥
9个月前
深入理解 C# 编程:枚举、文件处理、异常处理和数字相加
C枚举枚举是一个特殊的“类”,表示一组常量(不可更改/只读变量)。要创建枚举,请使用enum关键字(而不是class或interface),并用逗号分隔枚举项:csharpenumLevelLow,Medium,High您可以使用点语法访问枚举项:csha