Java枚举的小知识点

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>> T valueOf(Class<T> 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. }

点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java枚举类型enum的使用

java枚举类型enum的使用最近跟同事讨论问题的时候,突然同事提到我们为什么java中定义的常量值不采用enmu枚举类型,而采用publicfinalstatic 类型来定义呢?以前我们都是采用这种方式定义的,很少采用enum定义,所以也都没有注意过,面对突入起来的问题,还真有点不太清楚为什么有这样的定义。既然不明白就抽

java枚举

https://www.cnblogs.com/hyl8218/p/5088287.html摘抄并自查语法(定义)创建枚举类型要使用enum关键字,隐含了所创建的类型都是java.lang.Enum类的子类。枚举类符合通用模式ClassEnum<EextendsEnum<E,而E表示枚举类型的名称。枚举类型的每一

java枚举类

使用enum声明,默认直接继承了java.lang.Enum类,而不是Object类;枚举类的对象是固定的,实例个数有限,不可以再new(),枚举对象后可以跟()。枚举元素必须位于枚举类体中的最开始部分,枚举元素后要有分号与其他成员分隔。枚举类的构造方法的权限修饰符默认是private;一旦枚举对象后面加上{},那么该对象实际是枚举匿名内部