枚举用法,单例模型
/** * 枚举的工具方法类提供格式化和解析LocalDate的方法 */ public enum DateUtil { INSTANCE;// 这就是一个枚举常量代表 DateUtil 的唯一实例 private final DateTimeFormatter formatter DateTimeFormatter.ofPattern(yyyy-MM-dd); public String formatDate(LocalDate date) { return date.format(formatter); } public LocalDate parseDate(String dateStr) { return LocalDate.parse(dateStr, formatter); } public static void main(String[] args) { System.out.println(DateUtil.INSTANCE.formatDate(LocalDate.now())); } }这里INSTANCE表示DateUtil枚举的唯一实例通过DateUtil.INSTANCE即可访问。它具备以下特性单例性JVM 保证每个枚举值只有一个实例DateUtil.INSTANCE全局唯一。线程安全实例化由 JVM 在类加载时完成天然线程安全。序列化安全枚举的序列化机制保证反序列化时不会创建新实例。反射安全无法通过反射创建枚举实例。因此INSTANCE常用于实现单例模式例如工具类、配置类等场景既简洁又安全。public enum ErrorCode { SUCCESS(0, 成功), PARAM_ERROR(1001, 参数错误), SYSTEM_ERROR(5001, 系统错误); private final int code; private final String message; ErrorCode(int code, String message) { this.code code; this.message message; } // 通过code查找枚举 public static ErrorCode valueOf(int code) { return Arrays.stream(values()) .filter(e - e.code code) .findFirst() .orElse(SYSTEM_ERROR); } public int getCode() { return code; } public String getMessage() { return message; } public static void main(String[] args) { ErrorCode errorCode ErrorCode.valueOf(1001); System.out.println(errorCode.getMessage()); } }/** * 1. 枚举抽象方法策略模式 * */ public enum Operation { PLUS { Override public int apply(int x, int y) { return x y; } }, MINUS { Override public int apply(int x, int y) { return x - y; } }, MULTIPLY { Override public int apply(int x, int y) { return x * y; } }; public abstract int apply(int x, int y); public static void main(String[] args) { // 使用 int result Operation.PLUS.apply(5, 3); // 返回 8 System.out.println(result: result); } }/** * 2. 枚举实现接口 */ public enum FileOperation implements Command{ OPEN { Override public void execute() { System.out.println(打开文件); } }, SAVE { Override public void execute() { System.out.println(保存文件); } }; public static void main(String[] args) { // 使用 FileOperation.OPEN.execute(); } } public interface Command { void execute(); }public enum OrderStatus { CREATED { Override public OrderStatus next() { return PAID; } }, PAID { Override public OrderStatus next() { return SHIPPED; } }, SHIPPED { Override public OrderStatus next() { return DELIVERED; } }, DELIVERED { Override public OrderStatus next() { return this; // 最终状态 } }; public abstract OrderStatus next(); public static void main(String[] args) { OrderStatus status OrderStatus.CREATED; System.out.println(status.next()); } }/** 在Java枚举中valueOf() 是一个静态方法它的作用是 将字符串转换为对应的枚举值. // 将字符串 ALIPAY 转换为枚举值 PaymentMethod.ALIPAY PaymentMethod paymentMethod PaymentMethod.valueOf(ALIPAY); // 将字符串 WECHAT 转换为枚举值 PaymentMethod.WECHAT PaymentMethod paymentMethod PaymentMethod.valueOf(WECHAT); / public enum PaymentMethod { ALIPAY { Override public PaymentStrategy createStrategy() { return new AlipayStrategy(); } }, WECHAT { Override public PaymentStrategy createStrategy() { return new WechatStrategy(); } }; public abstract PaymentStrategy createStrategy(); // 静态工厂方法 public static PaymentStrategy getStrategy(String method) { return valueOf(method.toUpperCase()).createStrategy(); } public static void main(String[] args) { PaymentStrategy alipayStrategy getStrategy(alipay); alipayStrategy.pay(); } } public interface PaymentStrategy { void pay(); } public class AlipayStrategy implements PaymentStrategy { Override public void pay() { System.out.println(支付宝支付); } } public class WechatStrategy implements PaymentStrategy { Override public void pay() { System.out.println(微信支付); } }public enum Permission { READ(1), // 0001 WRITE(2), // 0010 EXECUTE(4), // 0100 DELETE(8); // 1000 private final int mask; Permission(int mask) { this.mask mask; } public int getMask() { return mask; } // 权限组合 public static int combine(Permission... permissions) { return Arrays.stream(permissions) .mapToInt(Permission::getMask) .reduce(0, (a, b) - a | b); } // 检查权限 public static boolean hasPermission(int permissions, Permission permission) { return (permissions permission.getMask()) ! 0; } public static void main(String[] args) { // 使用 int myPermissions Permission.combine(Permission.READ, Permission.WRITE); System.out.println(myPermissions myPermissions ); boolean canWrite Permission.hasPermission(myPermissions, Permission.WRITE); System.out.println(canWrite canWrite ); } }public enum PizzaSize { SMALL(30, 25.0), MEDIUM(35, 35.0), LARGE(40, 45.0); private final int diameter; private final double price; PizzaSize(int diameter, double price) { this.diameter diameter; this.price price; } public int getDiameter() { return diameter; } public double getPrice() { return price; } /** * 语法特点 * 箭头语法使用 - 而不是传统的 : * 直接返回值不需要 break 语句每个 case 直接返回结果 * 表达式特性整个 switch 可以作为一个表达式使用有返回值 * * 优势 * 更简洁代码行数减少 * 更安全避免了忘记写 break 导致的 fall-through 问题 * 更直观每个 case 直接对应一个返回值 * */ // public PizzaSize upgrade() { // return switch (this) { // case SMALL - MEDIUM; // case MEDIUM - LARGE; // case LARGE - LARGE; // 已经是最大 // }; // } /** * 主要变化说明 * 语法结构 * * 从 switch (this) { case SMALL - MEDIUM; } 改为传统的 switch-case 语法 * 使用冒号 : 而不是箭头 - * 每个case需要明确的 return 语句 * 添加default分支 * * 在Java 8中建议添加default分支来处理未知情况 * 防止未来添加新的枚举值时出现未处理的情况 * 代码风格 * * 每个case分支独占一行提高可读性 * 保持原有的注释说明 * * return */ public PizzaSize upgrade() { switch (this) { case SMALL: return MEDIUM; case MEDIUM: return LARGE; case LARGE: return LARGE; // 已经是最大 default: throw new IllegalArgumentException(Unknown pizza size: this); } } public static void main(String[] args) { PizzaSize size PizzaSize.SMALL; size size.upgrade(); System.out.println(size.getDiameter() : size.getPrice()); } }public enum ReportType { PDF { Override protected String generateHeader() { return PDF Header; } Override protected String generateFooter() { return PDF Footer; } }, EXCEL { Override protected String generateHeader() { return Excel Header; } Override protected String generateFooter() { return Excel Footer; } }; // 模板方法 public final String generateReport(String content) { return generateHeader() \n content \n generateFooter(); } protected abstract String generateHeader(); protected abstract String generateFooter(); public static void main(String[] args) { ReportType reportType ReportType.PDF; String report reportType.generateReport(Hello World); System.out.println(report: report); } }package com.hihonor.marketing.crowd; /** * 枚举值本质上是单例模式而且是Java中实现单例模式的最佳方式。 * 为什么枚举是天然的单例 * JVM保证唯一性每个枚举值在JVM中只有一个实例 * 线程安全枚举的实例化由JVM在类加载时完成天然线程安全 * 序列化安全枚举的序列化机制保证了反序列化时不会创建新实例 * 反射安全无法通过反射创建枚举实例 * * 这种写法确保了 * Singleton.INSTANCE 在整个JVM中只有一个实例 * 线程安全无需额外的同步机制 * 序列化和反序列化安全 * 总结 * 枚举值确实是单例模式而且是《Effective Java》作者Joshua Bloch推荐的实现单例的最佳方式。它解决了传统单例实现中的线程安全、序列化、反射攻击等问题代码简洁且功能强大。 */ public enum Singleton { INSTANCE;// 这就是一个单例实例 private int counter 0; public void doSomething() { counter; System.out.println(执行次数: counter); } public static void main(String[] args) { // 使用 - 线程安全防止反射攻击 Singleton.INSTANCE.doSomething(); } }public enum Validator { NOT_NULL(Objects::nonNull, 不能为空), NOT_BLANK(s - s ! null !s.toString().trim().isEmpty(), 不能为空或空白), POSITIVE(n - n ! null ((Number)n).doubleValue() 0, 必须为正数); private final PredicateObject predicate; private final String message; Validator(PredicateObject predicate, String message) { this.predicate predicate; this.message message; } public boolean validate(Object value) { return predicate.test(value); } public String getMessage() { return message; } public static void main(String[] args) { System.out.println(Validator.NOT_NULL.validate(hello)); System.out.println(Validator.NOT_NULL.validate(null)); } }

相关新闻

C语言分支和循环语句详解

C语言分支和循环语句详解

在C语言中,程序的执行流程并非总是按顺序线性推进。分支语句的核心作用,就是让程序能够根据不同的条件,选择执行不同的代码块,从而实现灵活的逻辑判断。一、if 语句if 是最基础的分支判断工具,它通过检查一个条件表达式…

2026/10/13 2:22:28 阅读更多 →
嵌入式Linux UVC驱动调试实战:从设备枚举到安卓Camera打通

嵌入式Linux UVC驱动调试实战:从设备枚举到安卓Camera打通

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 2:22:28 阅读更多 →
从决策记录到自动化流水线:architecture-decision-record 仓库“持续集成”ADR 示例的完整解读与落地实践

从决策记录到自动化流水线:architecture-decision-record 仓库“持续集成”ADR 示例的完整解读与落地实践

【免费下载链接】architecture-decision-record Architecture decision record (ADR) examples for software planning, IT leadership, and template documentation 项目地址: https://gitcode.com/gh_mirrors/ar/architecture-decision-record 点击查看 免费下载 …

2026/10/13 2:21:28 阅读更多 →

最新新闻

孩子专注力不足怎么办:从环境到方法,家长可操作的完整指南

孩子专注力不足怎么办:从环境到方法,家长可操作的完整指南

孩子一写作业就抠橡皮、发呆、上厕所,老师隔三差五反馈上课走神,可一玩起乐高、看起动画片又比谁都专注。这是我在后台被问到最多的育儿问题之一。专注力不足,听起来像是孩子的问题,但我在接触了大量家庭后发现,多数情…

2026/10/13 3:01:43 阅读更多 →
从Java UI到ArkUI:鸿蒙多端适配与声明式开发实战

从Java UI到ArkUI:鸿蒙多端适配与声明式开发实战

一个明显的感觉是,手机、平板、手表基本是"三个项目三套代码"。虽然底层都是 Java,但 UI 层几乎没法复用——手表的圆形屏幕、平板的横竖屏适配、折叠屏的展开收起,每个场景都要单独处理。项目里多一套设备,就意味着多一…

2026/10/13 3:01:43 阅读更多 →
炒股注意事项:从买卖点到心态纪律的完整交易体系

炒股注意事项:从买卖点到心态纪律的完整交易体系

做股票交易这行,时间越长越会发现一个道理:真正拉开人与人差距的,往往不是谁更聪明、谁的消息更灵通,而是谁更能守住交易里的那些“注意事项”。这行里有一句话流传很广:“会买的是徒弟,会卖的是师傅&#…

2026/10/13 3:01:43 阅读更多 →
Hadoop MapReduce 核心流程:从 Input 到 Reduce

Hadoop MapReduce 核心流程:从 Input 到 Reduce

MapReduce 是分而治之的分布式计算模型,分为两大阶段:Map 阶段(映射)和Reduce 阶段(归约),中间由 Shuffle 洗牌过程衔接。整体流程:输入分片 → Map任务 → Shuffle(分区…

2026/10/13 3:01:43 阅读更多 →
artcraft式创作工具:从意图解析到资产生成的工程实践

artcraft式创作工具:从意图解析到资产生成的工程实践

1. 从“artcraft”这个名字说起:它到底想解决什么问题第一次看到“artcraft”这个词,我脑子里蹦出来的不是某个具体工具,而是一种很朴素的组合感——art 加上 craft,艺术加手艺。这两个词放在一起,本身就带着一种张力&…

2026/10/13 3:01:43 阅读更多 →
精读原型网络:从少样本学习到类均值分类器的度量学习基石

精读原型网络:从少样本学习到类均值分类器的度量学习基石

最近在整理少样本学习(few-shot learning)方向的文献时,我重新精读了《Prototypical Networks for Few-shot Learning》这篇论文。它发表于2017年底,属于度量学习路线里绕不开的基石工作。整篇论文的思想非常朴素:用每…

2026/10/13 3:00:43 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →