程序人生——Java枚举和注解使用建议

本文详细介绍了Java中的枚举和注解的最佳实践,包括如何使用枚举定义常量、构造函数增强描述、处理switch中的空值异常、valueOf方法的校验、实现工厂方法模式以及JVM内存分配、类加载、垃圾回收和多线程编程的相关知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

引出

程序人生——Java枚举和注解使用建议


枚举和注解

建议83:推荐使用枚举定义常量

  • 在项目开发中,推荐使用枚举常量替代接口常量和类常量)(常量分为:类常量、接口常量、枚举常量

  • 枚举常量

    优点

    • 1、枚举常量更简单;
    • 2、枚举常量属于稳态性(不允许发生越界);
    • 3、枚举具有内置方法,values方法可以获取到所有枚举值;
    • 4、枚举可以自定义方法

建议84:使用构造函数协助描述枚举项

  • 每个枚举项都是该枚举的一个实例。可以通过添加属性,然后通过构造函数给枚举项添加更多描述信息

建议85:小心switch带来的空值异常

  • 使用枚举值作为switch(枚举类);语句的条件值时,需要对枚举类进行判断是否为null值。因为Java中的switch语句只能判断byte、short、char、int类型,JDK7可以判断String类型,使用switch语句判断枚举类型时,会根据枚举的排序值匹配。如果传入的只是null的话,获取排序值需要调用如season.ordinal()方法时会抛出NullPointerException异常

建议86:在switch的default代码块中增加AssertionError错误

  • switch语句在使用枚举类作为判断条件时,避免出现增加了一个枚举项,而switch语句没做任何修改,编译不会出现问题,但是在运行期会发生非预期的错误。为避免这种情况出现,建议在default后直接抛出一个AssertionError错误。含义是:不要跑到这里来,一跑到这里来马上就会报错

建议87:使用valueOf前必须进行校验

  • Enum.valueOf()方法会把一个String类型的名称转变为枚举项,也就是在枚举项中查找出字面值与该参数相等的枚举项。valueOf方法先通过反射从枚举类的常量声明中查找,若找到就直接返回,若找不到就抛出IllegalArgumentException异常

建议88:用枚举实现工厂方法模式更简洁

  • 工厂方法模式是“创建对象的接口,让子类决定实例化哪一个类,并使一个类的实例化延迟到其子类”。枚举实现工厂方法模式有两种方法:1、枚举非静态方法实现工厂方法模式;2、通过抽象方法生成产品;优点:1、避免错误调用的发生;2、性能好,使用便捷;3、减低类间耦合性

建议89:枚举项的数量控制在64个以内

  • Java提供了两个枚举集合:EnumSet、EnumMap;EnumSet要求其元素必须是某一枚举的枚举项,EnumMap表示Key值必须是某一枚举的枚举项。由于枚举类型的实例数量固定并且有限,相对来说EnumSet和EnumMap的效率会比其他Set和Map要高。Java处理EnumSet过程:当枚举项小于等于64时,创建一个RegularEnumSet实例对象,大于64时创一个JumboEnumSet实例对象。RegularEnumSet是把每个枚举项编码映射到一个long类型数字得每一位上,而JumboEnumSet则会先按照64个一组进行拆分,然后每个组再映射到一个long类型的数字得每一位上

建议90:小心注解继承

  • 不常用的元注解(Meta-Annotation):@Inherited,它表示一个注解是否可以自动被继承

建议91:枚举和注解结合使用威力更大

  • 注解和接口写法类似,都采用了关键字interface,而且都不能有实现代码,常量定义默认都是public static final类型的等,他们的主要不同点:注解要在interface前加上@字符,而且不能继承,不能实现

建议92:注意@Override不同版本的区别

  • @Override注解用于方法的覆写上,它在编译期有效,也就是Java编译器在编译时会根据该注解检查方法是否真的是覆写,如果不是就报错,拒绝编译。Java1.5版本中@Override是严格遵守覆写的定义:子类方法与父类方法必须具有相同的方法名、输入参数、输出参数(允许子类缩小)、访问权限(允许子类扩大),父类必须是一个类,不是是接口,否则不能算是覆写。而在Java1.6就开放了很多,实现接口的方法也可以加上@Override注解了。如果是Java1.6版本移植到Java1.5版本中时,需要删除接口实现方法上的@Override注解

深入认识JVM

JVM内存分配,类加载

Java进阶(1)——JVM的内存分配 & 反射Class类的类对象 & 创建对象的几种方式 & 类加载(何时进入内存JVM)& 注解 & 反射+注解的案例

在这里插入图片描述

创建对象的4种方法总结

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化

在这里插入图片描述

垃圾回收GC

在这里插入图片描述

Java进阶(垃圾回收GC)——理论篇:JVM内存模型 & 垃圾回收定位清除算法 & JVM中的垃圾回收器

简介:本篇博客介绍JVM的内存模型,对比了1.7和1.8的内存模型的变化;介绍了垃圾回收的语言发展;阐述了定位垃圾的方法,引用计数法和可达性分析发以及垃圾清除算法;然后介绍了Java中的垃圾回收器,由串行、到并行再到并发,最后到G1的演变;最后给出了垃圾回收器的对比和使用指引。

JVM调优,Arthas使用

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

认识多线程

创建多线程方法+了解线程池

Java进阶(5)——创建多线程的方法extends Thread和implements Runnable的对比 & 线程池及常用的线程池

在这里插入图片描述

多线程下-1非原子性问题即解决

Java进阶(6)——抢购问题中的数据不安全(非原子性问题)& Java中的synchronize和ReentrantLock锁使用 & 死锁及其产生的条件

在这里插入图片描述

再论线程,创建、生命周期

Java进阶(再论线程)——线程的4种创建方式 & 线程的生命周期 & 线程的3大特性 & 集合中的线程安全问题

主要内容:
1.线程创建的方式,继承Thread类,实现Runable接口,实现Callable接口,采用线程池;
2.线程生命周期: join():运行结束再下一个, yield():暂时让出cpu的使用权,deamon():守护线程,最后结束,sleep():如果有锁,不会让出;
3.线程3大特性,原子性,可见性,有序性;
4.list集合中线程安全问题,hash算法问题;


总结

程序人生——Java枚举和注解使用建议

### Java 枚举类型与数据库交互的最佳实践 在Java中,枚举类型的使用可以极大地简化代码逻辑并提高程序的可读性健壮性。当涉及到与数据库交互时,通过合理利用框架的支持设计模式,可以使这一过程更加顺畅。 #### 使用 MyBatis Plus 实现枚举映射 MyBatisPlus 提供了专门用于处理枚举转换的功能,使得可以在实体类字段上直接标注特定注解来完成自动化的序列化/反序列化工作[^1]。这不仅减少了手动编码的工作量,也降低了潜在错误的发生几率。 例如,在定义一个表示用户状态的枚举 `UserStatus` 之后: ```java public enum UserStatus { ACTIVE, INACTIVE; } ``` 可以通过如下方式将其绑定至对应的数据库列: ```java @TableField(fill = FieldFill.INSERT_UPDATE) @EnumValue private UserStatus status; ``` 这里使用的 `@EnumValue` 注解会告诉 MyBatisPlus 将该属性视为枚举值,并按照预设规则存储到数据库中或从数据库加载回内存对象。 #### 利用 EnumMap 进行高效的键值对管理 除了借助 ORM 框架外,还可以采用原生的方式如 `EnumMap` 来管理操作基于枚举的数据集。这种方式特别适合于那些不需要持久保存但在运行期间频繁访问的情况[^3]。下面是一个简单的例子展示了如何创建操作这样的映射关系: ```java // 定义 PlayerType 枚举 enum PlayerType { BASKETBALL, FOOTBALL, TENNIS } // 创建 EnumMap 并填充初始数据 EnumMap<PlayerType, String> playerDescriptions = new EnumMap<>(PlayerType.class); playerDescriptions.put(PlayerType.BASKETBALL, "篮球运动员"); playerDescriptions.put(PlayerType.FOOTBALL, "足球运动员"); playerDescriptions.put(PlayerType.TENNIS, "网球运动员"); System.out.println(playerDescriptions); // 输出全部条目 System.out.println(playerDescriptions.get(PlayerType.BASKALL)); // 获取指定项描述 System.out.println(playerDescriptions.containsKey(PlayerType.BASKETBALL)); // 检查是否存在某一项 System.out.println(playerDescriptions.remove(PlayerType.BASKETBALL)); // 移除某个元素 ``` 上述代码片段说明了怎样快速构建起一套以枚举为基础的信息检索系统,同时也体现了其灵活性——能够方便地增删改查各个成员关联的具体信息。 #### 数据库层面的设计考量 考虑到实际应用场景下的需求多样性,有时还需要针对具体业务场景调整数据库端的相关配置。比如设置合适的默认值、约束条件等,从而保障数据的一致性完整性[^2]。此外,对于大规模并发请求而言,则需进一步考虑索引优化等问题,确保查询效率不受影响。 综上所述,通过结合使用像 MyBatisPlus 这样的高级工具包以及遵循良好的编程习惯(如善用集合类),完全可以实现既高效又易于维护的 Java 应用程序与数据库之间的通信机制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Arya's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值