当前位置: 首页 > news >正文

Java 枚举(Enum)的使用说明

在 Java 中,枚举(Enum)是一种特殊的数据类型,用于定义一组固定的命名常量。它比传统的常量(如 public static final)更安全、更灵活,且支持面向对象特性。以下是枚举的详细用法:


1. 基础定义与使用

java

复制

下载

public enum Direction {NORTH, SOUTH, EAST, WEST  // 枚举常量(全大写命名)
}// 使用示例
Direction dir = Direction.NORTH;
System.out.println(dir); // 输出: NORTH

2. 添加成员变量和方法

枚举可以有字段、构造方法和自定义方法:

java

复制

下载

public enum Planet {// 枚举常量 + 构造参数MERCURY(3.303e23, 2.4397e6),VENUS(4.869e24, 6.0518e6);private final double mass;   // 质量(kg)private final double radius; // 半径(m)// 构造方法(必须是 private)Planet(double mass, double radius) {this.mass = mass;this.radius = radius;}// 自定义方法public double surfaceGravity() {return 6.67430e-11 * mass / (radius * radius);}
}// 使用
double gravity = Planet.MERCURY.surfaceGravity();

3. 覆盖枚举常量的方法

每个常量可以有自己的方法实现:

java

复制

下载

public enum Operation {ADD {public double apply(double x, double y) { return x + y; }},SUBTRACT {public double apply(double x, double y) { return x - y; }};public abstract double apply(double x, double y); // 抽象方法
}// 使用
double result = Operation.ADD.apply(5, 3); // 返回 8

4. 常用内置方法

  • values():获取所有枚举值

  • valueOf(String name):通过名称获取枚举常量

  • name() 和 ordinal():获取常量名和顺序位置

java

复制

下载

Direction[] allDirections = Direction.values(); // [NORTH, SOUTH, EAST, WEST]
Direction east = Direction.valueOf("EAST");    // 字符串转枚举
System.out.println(east.name());     // 输出 "EAST"
System.out.println(east.ordinal());  // 输出 2(索引从0开始)

5. 实现接口

枚举可以实现接口,统一或分别实现方法:

java

复制

下载

public interface Command {void execute();
}public enum FileOperation implements Command {OPEN {public void execute() { System.out.println("打开文件"); }},SAVE {public void execute() { System.out.println("保存文件"); }};
}// 使用
FileOperation.OPEN.execute(); // 输出 "打开文件"

6. 在 switch 语句中使用

java

复制

下载

Direction dir = Direction.NORTH;
switch (dir) {case NORTH:System.out.println("向北");break;case SOUTH:System.out.println("向南");break;// ...其他 case
}

7. 单例模式(线程安全)

枚举是实现单例的最佳方式(避免反射攻击):

java

复制

下载

public enum Singleton {INSTANCE;public void doSomething() {System.out.println("单例操作");}
}// 使用
Singleton.INSTANCE.doSomething();

关键特性总结

特性说明
类型安全编译时检查,避免传入无效值
固定实例枚举常量在 JVM 中是唯一的(== 比较安全)
支持 OOP可包含字段、方法、构造方法,实现接口,覆盖方法
线程安全枚举实例的创建由 JVM 保证,天然适合单例
序列化安全无需额外处理,Java 原生支持枚举的序列化与反序列化

何时使用枚举?

  • 需要一组预定义的常量(如状态、类型、方向等)

  • 需要类型安全且易读的常量

  • 需要为常量附加行为(方法)

  • 实现单例模式

通过合理使用枚举,可以大幅提升代码的可读性、安全性和可维护性。

Java 枚举类型完整示例

下面是一个完整的Java枚举使用示例,展示了枚举的各种特性:

import java.time.DayOfWeek;public class EnumExample {// 1. 基本枚举定义public enum Season {SPRING, SUMMER, AUTUMN, WINTER}// 2. 带属性和方法的枚举public enum Planet {MERCURY(3.303e23, 2.4397e6),VENUS(4.869e24, 6.0518e6),EARTH(5.976e24, 6.37814e6),MARS(6.421e23, 3.3972e6),JUPITER(1.9e27, 7.1492e7),SATURN(5.688e26, 6.0268e7),URANUS(8.686e25, 2.5559e7),NEPTUNE(1.024e26, 2.4746e7);private final double mass;   // 千克private final double radius; // 米// 私有构造函数Planet(double mass, double radius) {this.mass = mass;this.radius = radius;}public double getMass() {return mass;}public double getRadius() {return radius;}// 计算表面重力public double surfaceGravity() {final double G = 6.67430e-11; // 引力常数return G * mass / (radius * radius);}// 计算重量public double surfaceWeight(double otherMass) {return otherMass * surfaceGravity();}}// 3. 带抽象方法的枚举public enum Operation {ADD("+") {public double apply(double x, double y) {return x + y;}},SUBTRACT("-") {public double apply(double x, double y) {return x - y;}},MULTIPLY("*") {public double apply(double x, double y) {return x * y;}},DIVIDE("/") {public double apply(double x, double y) {if (y == 0) throw new ArithmeticException("Division by zero");return x / y;}};private final String symbol;Operation(String symbol) {this.symbol = symbol;}public String getSymbol() {return symbol;}// 抽象方法 - 每个枚举常量必须实现public abstract double apply(double x, double y);}// 4. 枚举实现接口public interface WorkSchedule {String getSchedule();}public enum WorkDay implements WorkSchedule {MONDAY("09:00-17:00") {public String getMotivation() {return "New week, new opportunities!";}},TUESDAY("09:00-17:00") {public String getMotivation() {return "Keep the momentum going!";}},WEDNESDAY("09:00-17:00") {public String getMotivation() {return "Halfway there!";}},THURSDAY("09:00-17:00") {public String getMotivation() {return "Almost there!";}},FRIDAY("09:00-16:00") {public String getMotivation() {return "Weekend is near!";}},SATURDAY("Day Off") {public String getMotivation() {return "Enjoy your weekend!";}},SUNDAY("Day Off") {public String getMotivation() {return "Rest and recharge!";}};private final String schedule;WorkDay(String schedule) {this.schedule = schedule;}@Overridepublic String getSchedule() {return schedule;}// 每个枚举常量可以有自己的方法实现public abstract String getMotivation();}public static void main(String[] args) {// 1. 基本枚举使用System.out.println("===== 基本枚举使用 =====");Season currentSeason = Season.SUMMER;System.out.println("当前季节: " + currentSeason);System.out.println("所有季节:");for (Season season : Season.values()) {System.out.println(season);}System.out.println();// 2. 带属性和方法的枚举System.out.println("===== 行星信息 =====");double earthWeight = 70; // 千克Planet earth = Planet.EARTH;System.out.printf("地球表面重力: %.2f m/s²%n", earth.surfaceGravity());System.out.printf("地球上 %.1f kg 的重量相当于: %n", earthWeight);for (Planet p : Planet.values()) {System.out.printf("在 %-8s上的重量: %6.1f kg%n", p, p.surfaceWeight(earthWeight));}System.out.println();// 3. 带抽象方法的枚举System.out.println("===== 数学运算 =====");double x = 10, y = 4;for (Operation op : Operation.values()) {System.out.printf("%.1f %s %.1f = %.1f%n", x, op.getSymbol(), y, op.apply(x, y));}System.out.println();// 4. 枚举实现接口System.out.println("===== 工作日安排 =====");DayOfWeek today = java.time.LocalDate.now().getDayOfWeek();WorkDay currentDay = WorkDay.valueOf(today.toString());System.out.println("今天是: " + currentDay);System.out.println("工作时间: " + currentDay.getSchedule());System.out.println("每日激励: " + currentDay.getMotivation());System.out.println();// 5. 在switch语句中使用枚举System.out.println("===== 根据季节推荐活动 =====");switch (currentSeason) {case SPRING:System.out.println("春天活动: 赏花、踏青");break;case SUMMER:System.out.println("夏天活动: 游泳、露营");break;case AUTUMN:System.out.println("秋天活动: 采摘、登山");break;case WINTER:System.out.println("冬天活动: 滑雪、泡温泉");break;}System.out.println();// 6. 单例模式System.out.println("===== 单例模式 =====");AppConfig config = AppConfig.INSTANCE;config.setAppName("Enum Demo App");System.out.println("应用名称: " + config.getAppName());System.out.println("配置ID: " + config.getConfigId());}// 7. 使用枚举实现单例模式public enum AppConfig {INSTANCE;private String appName;private final String configId = "CONFIG-" + System.currentTimeMillis();public String getAppName() {return appName;}public void setAppName(String appName) {this.appName = appName;}public String getConfigId() {return configId;}}
}

示例说明

1. 基本枚举 (Season)

  • 最简单的枚举形式,只有一组命名常量

  • 使用 values() 方法遍历所有枚举值

  • 直接打印枚举常量会输出其名称

2. 带属性和方法的枚举 (Planet)

  • 每个行星有质量和半径属性

  • 提供计算表面重力和重量的方法

  • 展示了如何使用枚举的构造函数初始化属性

3. 带抽象方法的枚举 (Operation)

  • 定义抽象方法 apply(),每个枚举常量必须实现

  • 每个运算有自己的符号表示

  • 演示了如何为不同枚举常量提供不同行为

4. 实现接口的枚举 (WorkDay)

  • 实现 WorkSchedule 接口

  • 每个工作日有自己的时间安排

  • 每个枚举常量有自己的激励语实现

  • 结合Java 8的日期API获取当前星期几

5. switch语句中使用枚举

  • 根据当前季节推荐不同的活动

  • 展示了枚举在switch语句中的类型安全特性

6. 单例模式实现 (AppConfig)

  • 使用枚举实现线程安全的单例

  • 包含配置属性和访问方法

  • 展示了枚举如何防止反射攻击和序列化问题

运行结果

运行此程序将输出类似以下内容(具体结果取决于运行时的日期):

text

复制

下载

===== 基本枚举使用 =====
当前季节: SUMMER
所有季节:
SPRING
SUMMER
AUTUMN
WINTER===== 行星信息 =====
地球表面重力: 9.80 m/s²
地球上 70.0 kg 的重量相当于: 
在 MERCURY 上的重量:   26.4 kg
在 VENUS   上的重量:   63.1 kg
在 EARTH   上的重量:   70.0 kg
在 MARS    上的重量:   26.5 kg
在 JUPITER 上的重量:  177.0 kg
在 SATURN  上的重量:   74.9 kg
在 URANUS  上的重量:   63.5 kg
在 NEPTUNE 上的重量:   79.6 kg===== 数学运算 =====
10.0 + 4.0 = 14.0
10.0 - 4.0 = 6.0
10.0 * 4.0 = 40.0
10.0 / 4.0 = 2.5===== 工作日安排 =====
今天是: WEDNESDAY
工作时间: 09:00-17:00
每日激励: Halfway there!===== 根据季节推荐活动 =====
夏天活动: 游泳、露营===== 单例模式 =====
应用名称: Enum Demo App
配置ID: CONFIG-1717999999999

这个示例全面展示了Java枚举的各种特性,包括基本用法、带属性和方法的枚举、抽象方法实现、接口实现、在switch语句中使用以及实现单例模式。

 

相关文章:

  • tomcat的websocket协议升级。如何从报文交换变成全双工通信?session对象的注册和绑定?
  • 【WebRTC-14】webrtc是如何创建视频的软/硬编码器?
  • Linux ELF文件详解:深入理解可执行文件格式
  • 【模板编程】
  • Java八股文——JVM「类加载篇」
  • websocket实践
  • (41)课60--61高级篇: MySQL体系结构(连接层、服务层、引擎层、存储层)。存储引擎是基于表的,可为不同表指定不同的存储引擎;查询表结构语句 show create table 表名
  • 鹰盾加密器“一机一码”技术全维度剖析:从底层实现到生态防护体系
  • 计算机网络面试汇总(完整版)
  • HTML 、CSS 、JavaScript基本简单介绍
  • docker详细操作--未完待续
  • TDengine 快速体验(Docker 镜像方式)
  • 手写muduo网络库(三):事件分发器(Poller,EPollPoller实现)
  • 邮科OEM摄像头图像处理技术:从硬件协同到智能进化
  • 微软PowerBI考试 PL300-在 Power BI 中设计语义模型 【附练习数据】
  • 高考倒计时(vb.net,持续更新版本)
  • 7.3.折半查找(二分查找)
  • Leetcode 3578. Count Partitions With Max-Min Difference at Most K
  • Oracle SQL*Plus 配置上下翻页功能
  • 行为设计模式之Memento(备忘录)
  • 大连网站制作公司58/网络培训
  • 企业网站的主要功能板块/360投放广告怎么收费
  • 大型网站的优化方法/seo排名优化推荐
  • 休闲会所网站建设/互联网产品营销策划方案
  • 域名到期网站/网站seo查询
  • 湖北做网站找谁/免费crm系统手机版