EXPLORE · 循迹而来

Java

FOLLOW YOUR CURIOSITY

把同一个话题,读得更深。

这个话题下有 88 篇手记。

设计模式

1755 阅读

本文围绕面向对象的设计原则与常用设计模式展开。概述了六大原则:单一职责、里氏替换、依赖倒置、接口隔离、迪米特(最少知识)和开闭原则,阐明其含义及对高内聚、低耦合、可复用、可维护和可扩展性的促进作用。随后给出单例模式的实现示例,包括饿汉式、懒汉式及其线程安全写法。最后介绍工厂模式的概念及实现,分别展示了简单工厂、工厂方法的代码结构,说明了工厂模式在把对象创建职责抽象化、解耦客户端与具体实现方面的价值。

UML

1555 阅读

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

Integer 和 Double 如何判断相等

1345 阅读

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

反射的基本概念

1257 阅读

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

用 IntegerCache 让 a 同时等于 1 和 2 和 3

1236 阅读

文章介绍利用 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 两种死循环的区别

1166 阅读

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

this与super关键字详解

1189 阅读

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

用枚举代替一组固定常量

1098 阅读

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

代码优化的部分实例

1302 阅读

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

mapstruct的基本使用

1337 阅读

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

Optional详解

1225 阅读

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文件进行两两对比并展示差异

1041 阅读

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