千家信息网

Java中的枚举相关知识点总结

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要讲解了"Java中的枚举相关知识点总结",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java中的枚举相关知识点总结"吧!Java中的枚举枚
千家信息网最后更新 2026年11月02日Java中的枚举相关知识点总结

这篇文章主要讲解了"Java中的枚举相关知识点总结",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java中的枚举相关知识点总结"吧!

Java中的枚举

枚举通常是一组相关的常量集合,其他编程语言很早就开始用枚举了,比如C++。从JDK1.5起,Java也开始支持枚举类型。

枚举是一种特殊的数据类型,它既是一种类(class)类型却又比类类型多了些特殊的约束,这些约束也造就了枚举类型的简洁性、安全性以及便捷性。

在Java中,通过enum来声明枚举类型,默认继承自java.lang.Enum。所以声明枚举类时无法再继承其他类。

枚举声明

在生活中我们会经常辨认方向,东南西北,它们的名称、属性等基本都是确定的,我们就可以将其声明为枚举类型:

public enum Direction {    EAST, WEST, NORTH, SOUTH; }

同样,每周七天也可以声明成枚举类型:

enum Day {     MONDAY, TUESDAY, WEDNESDAY,     THURSDAY, FRIDAY, SATURDAY, SUNDAY }

在没有枚举或没使用枚举的情况下,并不是说不可以定义变量,我们可以通过类或接口进行常量的定义:

public class Day {      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;  }

但这样存在许多不足,如在类型安全和使用方便性上。如果存在定义int值相同的变量,混淆的几率还是很大的,编译器也不会提出任何警告。因此,当能使用枚举的时候,并不提倡这种写法。

枚举的底层实现

上面我们已经说了,枚举是一个特殊的类,每一个枚举项本质上都是枚举类自身的实例。

因此,上面枚举类Direction可以通过下面代码进行示例:

final class Direction extends Enum{     public final static Direction EAST = new Direction();     public final static Direction WEST = new Direction();     public final static Direction NORTH = new Direction();     public final static Direction SOUTH = new Direction(); }

首先通过javac命令对Direction进行编译,然后通过javap命令来查看一下对应class文件内容:

bogon:enums apple$ javap Direction.class  Compiled from "Direction.java" public final class com.choupangxia.enums.Direction extends java.lang.Enum {   public static final com.choupangxia.enums.Direction EAST;   public static final com.choupangxia.enums.Direction WEST;   public static final com.choupangxia.enums.Direction NORTH;   public static final com.choupangxia.enums.Direction SOUTH;   public static com.choupangxia.enums.Direction[] values();   public static com.choupangxia.enums.Direction valueOf(java.lang.String);   static {}; }

可以看到,一个枚举在经过编译器编译过后,变成了一个抽象类,它继承了java.lang.Enum;而枚举中定义的枚举常量,变成了相应的public static final属性,而且其类型就抽象类的类型,名字就是枚举常量的名字。

枚举使用实例

通过上面的反编译我们可以看到,枚举的选项本质上就是public static final的变量,所以就把它当做这样的变量使用即可。

public class EnumExample {     public static void main(String[] args) {         Direction north = Direction.NORTH;         System.out.println(north);        //Prints NORTH     } }

枚举的ordinal()方法

ordinal()方法用于获取枚举变量在枚举类中声明的顺序,下标从0开始,与数组中的下标很相似。它的设计是用于EumSet和EnumMap复杂的基于枚举的数据结构使用。

Direction.EAST.ordinal();     //0   Direction.NORTH.ordinal();    //2

需要注意的是如果枚举项声明的位置发生了变化,那么ordinal方法的值也随之变化。所以,进来避免使用该方法。不然,当枚举项比较多时,别人在中间增删一项,会导致后续的所有顺序变化。

枚举的values()和valueOf()

values()方法可获取枚举类中的所有变量,并作为数组返回:

Direction[] directions = Direction.values();   for (Direction d : directions) {     System.out.println(d); }   //Output:   EAST WEST NORTH SOUTH

values()方法是由编译器插入到枚举类中的static方法,而它的父类Enum中并不存在这个方法。

valueOf(String name)方法与Enum类中的valueOf方法的作用类似根据名称获取枚举变量,同样是由编译器生成的,但更简洁些,只需传递一个参数。

Direction east = Direction.valueOf("EAST");           System.out.println(east);   //Output:   EAST

枚举命名约定

按照约定,枚举属于常量,因此采用所有字母大写,下划线分割的风格(UPPER_CASE)。也就是说枚举类名与普通类约定一样,而枚举中的变量与静态变量的命名规范一致。

枚举的构造方法

默认情况下,枚举类是不需要构造方法的,默认的变量就是声明时的字符串。当然,你也可以通过自定义构造方法,来初始化枚举的一些状态信息。通常情况下,我们会在构造参数中传入两个参数,比如,一个编码,一个描述。

以上面的方向为例:

public enum Direction {     // enum fields     EAST(0), WEST(180), NORTH(90), SOUTH(270);       // constructor     private Direction(final int angle) {         this.angle = angle;     }       // internal state     private int angle;       public int getAngle() {         return angle;     } }

如果我们想访问每个方向的角度,可以通过简单的方法调用:

Direction north = Direction.NORTH;           System.out.println(north);                      //NORTH   System.out.println(north.getAngle());           //90   System.out.println(Direction.NORTH.getAngle()); //90

枚举中的方法

枚举就是一个特殊的类,因此也可以像普通的类一样拥有方法和属性。在枚举中不仅可以声明具体的方法,还可以声明抽象方法。

方法的访问权限可以是private、protected和public。可以通过这些方法返回枚举项的值,也可以做一些内部的私有处理。

public enum Direction {     // enum fields     EAST, WEST, NORTH, SOUTH;           protected String printDirection() {         String message = "You are moving in " + this + " direction";         System.out.println( message );         return message;     } }

对应方法的使用如下:

Direction.NORTH.printDirection();  Direction.EAST.printDirection();

枚举类中还可以定义抽象的方法,但每个枚举项中必须实现对应的抽象方法:

public enum Direction  {     // enum fields     EAST {         @Override         public String printDirection() {             String message = "You are moving in east. You will face sun in morning time.";             return message;         }     },     WEST {         @Override         public String printDirection() {             String message = "You are moving in west. You will face sun in evening time.";             return message;         }     },     NORTH {         @Override         public String printDirection() {             String message = "You are moving in north. You will face head in daytime.";             return message;         }     },     SOUTH {         @Override         public String printDirection() {             String message = "You are moving in south. Sea ahead.";             return message;         }     };       public abstract String printDirection(); }

抽象方法的调用,与普通方法一样:

Direction.NORTH.printDirection();  Direction.EAST.printDirection();

通过这种方式就可以轻而易举地定义每个枚举实例的不同行为方式。比如需要每个枚举项都打印出方向的名称,就可以定义这么一个抽象的方法。

上面的实例enum类似乎表现出了多态的特性,可惜的是枚举类型的实例终究不能作为类型传递使用。下面的方式编译器都无法通过:

//无法通过编译,Direction.NORTH是个实例对象  public void text(Direction.NORTH instance){ }

枚举的继承

上面已经提到过枚举继承自java.lang.Enum,Enum是一个抽象类:

public abstract class Enum>         implements Comparable, Serializable {     // ... }

也就是说,所有的枚举类都支持比较(Comparable)和序列化(Serializable)的特性。也正因为所有的枚举类都继承了Enum,所以无法再继承其他类了,但是可以实现接口。

枚举的比较

所有的枚举默认都是Comparable和单例的,因此可以通过equals方法进行比较,甚至可以直接用双等号"=="进行比较。

Direction east = Direction.EAST; Direction eastNew = Direction.valueOf("EAST");   System.out.println( east == eastNew );           //true System.out.println( east.equals( eastNew ) );    //true

枚举集合:EnumSet和EnumMap

在java.util包下引入了两个枚举集合类:EnumSet和EnumMap。

EnumSet

EnumSet类的定义如下:

public abstract class EnumSet> extends AbstractSet     implements Cloneable, java.io.Serializable{     // ... }

EnumSet是与枚举类型一起使用的专用Set集合,EnumSet中所有元素都必须是枚举类型。与其他Set接口的实现类HashSet/TreeSet不同的是,EnumSet在内部实现是位向量。

位向量是一种极为高效的位运算操作,由于直接存储和操作都是bit,因此EnumSet空间和时间性能都十分可观,足以媲美传统上基于int的"位标志"的运算,关键是我们可像操作set集合一般来操作位运算。

EnumSet不允许使用null元素,试图插入null将抛出 NullPointerException,但测试判断是否存在null元素或移除null元素则不会抛出异常,与大多数Collection实现一样,EnumSet不是线程安全的,在多线程环境下需注意数据同步问题。

使用实例:

public class Test {    public static void main(String[] args) {      Set enumSet = EnumSet.of(  Direction.EAST,                                 Direction.WEST,                                 Direction.NORTH,                                 Direction.SOUTH                               );    }  }

EnumMap

EnumMap的声明如下:

public class EnumMap, V> extends AbstractMap     implements java.io.Serializable, Cloneable {}

与EnumSet类似,EnumMap是一个特殊的Map,Map的Key必须是枚举类型。EnumMap内部是通过数组实现的,效率比普通的Map更高一些。EnumMap的key值不能为null,并且EnumMap也不是线程安全的。

EnumMap使用实例如下:

public class Test {   public static void main(String[] args){     //Keys can be only of type Direction     Map enumMap = new EnumMap(Direction.class);       //Populate the Map     enumMap.put(Direction.EAST, Direction.EAST.getAngle());     enumMap.put(Direction.WEST, Direction.WEST.getAngle());     enumMap.put(Direction.NORTH, Direction.NORTH.getAngle());     enumMap.put(Direction.SOUTH, Direction.SOUTH.getAngle());   } }

枚举与switch

使用switch进行条件判断时,条件参数一般只能是整型,字符型,同时也支持枚举型,在java7后switch也对字符串进行了支持。

使用实例如下:

enum Color {GREEN,RED,BLUE}  public class EnumDemo4 {      public static void printName(Color color){         switch (color){             //无需使用Color进行引用             case BLUE:                  System.out.println("蓝色");                 break;             case RED:                 System.out.println("红色");                 break;             case GREEN:                 System.out.println("绿色");                 break;         }     }      public static void main(String[] args){         printName(Color.BLUE);         printName(Color.RED);         printName(Color.GREEN);     } }

枚举与单例

单例模式是日常使用中最常见的设计模式之一了,单例的实现有很多种实现方法(饿汉模式、懒汉模式等),这里就不再赘述,只以一个最普通的单例来做对照,进而看看基于枚举如何来实现单例模式。

饿汉模式的实现:

public class Singleton {      private static Singleton instance = new Singleton();      private Singleton() {     }      public static Singleton getInstance() {         return instance;     } }

简单直接,缺点是可能在还不需要时就把实例创建出来了,没起到lazy loading的效果。优点就是实现简单,而且安全可靠。

这样一个单例场景,如果通过枚举进行实现如下:

public enum Singleton {      INSTANCE;      public void doSomething() {         System.out.println("doSomething");     } }

在effective java中说道,最佳的单例实现模式就是枚举模式。利用枚举的特性,让JVM来帮我们保证线程安全和单一实例的问题。除此之外,写法还特别简单。

直接通过Singleton.INSTANCE.doSomething()的方式调用即可。方便、简洁又安全。

感谢各位的阅读,以上就是"Java中的枚举相关知识点总结"的内容了,经过本文的学习后,相信大家对Java中的枚举相关知识点总结这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

方法 类型 实例 变量 编译 模式 安全 就是 可以通过 知识 知识点 普通 特殊 常量 编译器 元素 参数 情况 方向 方式 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广东猪兼强互联网科技有限公司 新华互联网科技学院 平安科技 互联网 深圳天众互联网科技公司 互联网科技宣传片 国外互联网科技网站 多迪互联网科技有限公司 深圳前海聚择互联网科技有限公司 贵州叶脉互联网科技有限公司所属行业 互联网和黑科技的看法 福建科技产业互联网发展 浙江互联网科技研学营 语蝶互联网科技有限公司 互联网科技和信息 乌鲁木齐新华智原互联网科技学校 徐州市互联网科技有限公司 上海同邻互联网科技有限公司规模 银川新华互联网科技学校是国营吗 唐山双旺合互联网科技产业园 前海云享互联网科技 南京欣网互联网络科技 互联网金融监管科技数据 互联网科技垄断 互联网科技的未来发展 互联网科技教育视频 互联网软件和科技 晋城互联网科技 美国互联网科技实力 恒生科技指数 中概互联网 互联网 科技节活动 微视频大赛
0