Java

浏览该分类下的所有文章

UML

UML提供多种图形化符号描述系统的静态和动态结构,包括用例图、类图、时序图、协作图、状态图、活动图、构件图、部署图等。其中,用例图用于捕获需求并展示功能模块及其关系,类图描述类及类间关联,时序图展示对象交互及消息顺序,这三图是最关键的。

如何对Integer和Double类型判断相等?

Integer 与 Double 不能直接使用 `==`、字符串比较或 `compareTo` 进行相等判断,因为它们类型不同且 `compareTo` 只能在同类之间使用。两者都继承自 `Number`,该类提供 `intValue、doubleValue` 等转换方法。可先将 Integer 与 Double 转换为相同的基本类型(如 `double`),再使用 `==` 比较数值是否相等。示例代码展示了 `i.doubleValue() == d.doubleValue()` 返回 `true`,实现了正确的相等判断。

反射的基本概念

反射是一种在运行时动态获取、创建、检查和调用类及其成员(包括 private)的机制,核心类为 Class、Constructor、Method、Field。它可用于突破访问限制、实现自定义注解、动态加载第三方 jar、按需加载以缩短编译和初始化时间。实现原理是 ClassLoader 将 .class 文件加载后生成 Class 对象,反射通过上述四个类操作这些对象。优点是灵活自由,缺点包括性能下降、破坏封装导致安全风险以及 API 变动时的兼容性问题。适度、按需使用可将影响降至可接受范围。

如何让 a == 1 && a == 2 && a == 3同时成立?

文章介绍利用 Java 的 `IntegerCache` 缓存特性,使表达式 `a == 1 && a == 2 && a == 3` 成立。通过反射获取 `Integer` 的内部类 `IntegerCache`,把缓存中下标对应的对象(原本分别是 1、2、3)改为同一个实例(1),随后 `Integer.valueOf` 或强制装箱得到的对象均指向同一内存地址,比较结果为 `true`;而使用 `new Integer` 会创建全新对象,地址不同,比较为 `false`。文中给出完整代码、运行结果,并解释 `valueOf` 与 `new` 的实现差异,强调此技巧体现了对 JDK 源码和缓存机制的深入了解,可用于性能预热等实际场景。

for(;;)和while(true)的区别

文章说明 Java 中的两种死循环写法 `for(;;)` 与 `while(true)` 在功能上完全等价。通过对比 JDK 源码示例和编译后生成的字节码,发现两者的字节码已完全相同,现代编译器会进行等价优化。之所以很多作者仍倾向使用 `for(;;)`,是源于早期 C 语言和早期 Java 编译器中 `for(;;)` 生成的指令更少、占用更少内存的历史习惯。如今两者在性能和行为上没有差别,仅是编码风格的选择。

this与super关键字详解

本文系统阐述了 Java 中关键字 **this** 与 **super** 的概念、作用及使用规范。`this` 代表当前对象实例,可用于访问本类属性/方法、区分形参与成员变量、在构造函数首行调用本类其他构造器。`super` 代表直接父类对象,可调用父类非私有成员、区分同名属性/方法、在子类构造函数首行显式调用父类构造器。文中通过 Father‑Son 示例演示了隐式 `super()` 导致的编译错误及两种解决方案(添加无参构造或显式 `super(args)`),并对两关键字的查找范围、功能等差异进行对比总结。

还在频繁定义常量?不如试试用枚举代替

常量经常被写成一组固定字符串,实际应使用枚举。枚举本质是类,可定义属性、方法,提供类型安全、可直接在switch中使用、拥有values()遍历、可封装额外信息(如HttpStatus)并实现业务逻辑。相较于单纯的String常量,代码更简洁、可靠,且易于维护。虽不是所有常量都必须改为枚举,但在成员在编译期已确定的情形下,枚举是更优选择。

代码优化的部分实例

文章通过几个实际案例展示常见的代码优化手段。先用 String.format 代替“+”或 StringBuilder 拼接长字符串,提高可读性;再将普通 I/O 改为 BufferedInputStream/BufferedOutputStream 并使用缓冲区,显著提升文件读写性能;通过把循环中第二层集合转为 Map ,利用键直接查找,减少嵌套循环次数;强调使用完 ResultSet、PreparedStatement、Connection 等资源后必须按顺序关闭,防止泄漏;最后指出频繁创建数据库连接的开销,推荐使用 Druid、C3P0 等连接池来复用连接,提高并发和稳定性。整体强调简洁、可读、低耗资源的编程实践。

mapstruct的基本使用

MapStruct 是基于注解的编译期代码生成器,可通过普通 getter/setter 实现类型安全、无反射的对象映射,避免手写冗余代码并在编译时捕获映射不完整或类型不匹配的问题。文章先展示了原始的博客评论接口实现,代码臃肿且不易维护,随后引入 MapStruct 依赖并创建 `CommentInfoConverter` 接口,在其中通过默认方法把 `HttpServletRequest` 的参数转换为 `Comments` 实体,控制层只需调用 `commentInfoConverter.map(request)` 即可完成对象构建,代码更简洁。最后给出运行时报的 `NullPointerException` 堆栈,提示在使用旧版 1.2.0.CR1 时可能出现内部处理错误。

Optional详解

Optional 是 Java 8 为避免 NPE 而提供的容器类,使用 of、ofNullable、empty 创建实例,内部不可直接 new。常用方法包括:get 在值为空时抛异常;isPresent 判断是否非空;ifPresent 为空时不执行,非空时执行 Consumer;filter 根据 Predicate 过滤返回自身或空 Optional;map 将值映射为新对象并包装;flatMap 直接返回另一个 Optional;orElse、orElseGet、orElseThrow 在值为空时分别返回默认值、惰性 Supplier 或抛自定义异常。文中通过 Person 示例演示各方法用法,并给出 Service 层查询、DAO 返回 Optional 的实战场景,强调根据业务需求选用合适方法以提升代码可读性和安全性。

Java实现对某一文件夹下的所有txt文件进行两两对比并展示差异

本文展示了如何使用 Java 对指定文件夹下的所有 txt 文件两两配对并输出差异。首先在 D:/txt 目录收集 .txt 文件列表(忽略非 txt 与子目录),随后按顺序每次取相邻的两个文件读取为 UTF‑8 字符串,比较整体相等性并在相同情况下提示。若不同,则按行拆分,分别遍历旧文件和新文件的每一行,对比对应行内容并打印不一致的行号及文本;当新文件行数超过旧文件时亦会输出多余行。代码使用了 Hutool 的集合工具进行空判断,并通过 FileInputStream 读取文件字节。运行后可直观看到每对文件的相同/不同信息以及具体差异行。

StringUtils部分API的用法与区别

本文系统演示了 Apache Commons‑Lang3 中 `StringUtils` 常用判断 API 的使用差异。通过示例代码说明:`isEmpty` 只判断 null 与空串,不把空格算作空;`isAnyEmpty` 任意参数为 null/空串即返回 true;`isNoneEmpty` 与 `!isAnyEmpty` 等价,所有参数均非空才为 true;`isBlank` 同时把空格视为空值;`isAnyBlank`、`isNoneBlank` 分别检测是否存在或全部不存在空格或空值。文末列出 `StringUtils` 其它常用方法(trim、equals、startsWith、split、replace、pad 等)并提供官方文档链接,帮助读者快速选用合适的字符串工具。