hutool的strutil、datetimeutil、jsonutil和fileutil/streamutil分别简化字符串处理、时间解析、json转换及文件io操作,统一边界、容忍null、自动适配常见格式且api语义清晰。

String操作太啰嗦?用StrUtil代替StringUtils和手写判断
Java原生字符串处理常要判空、去前后空格、截取、拼接,还容易漏掉null安全。Hutool的StrUtil把这事做薄了——它默认容忍null,所有方法都返回String或boolean,不抛NullPointerException。
常见错误现象:用org.apache.commons.lang3.StringUtils时忘记先判空,或自己写str != null && !str.trim().isEmpty(),逻辑分散又易错。
-
StrUtil.isBlank(" \t\n ")→true(自动trim+判空,null也安全) -
StrUtil.subBetween("【订单号:12345】", "【", "】")→"订单号:12345"(比substring+indexOf组合清晰得多) -
StrUtil.format("用户{}登录失败,次数{}", "zhangsan", 3)→"用户zhangsan登录失败,次数3"(不依赖MessageFormat或String.format的异常风险)
注意:StrUtil不替换String原生方法,而是补足高频但原生缺失的语义,比如StrUtil.equalsAny("a", "a", "b", "c")这种多值等值判断,原生没对应API。
日期解析总出错?DateTimeUtil统一收口时间处理
Java 8 的LocalDateTime.parse对格式敏感,一个空格、一个字母大小写不对就抛DateTimeParseException;而老项目还在用SimpleDateFormat,线程不安全又难维护。Hutool的DateTimeUtil做了两件事:自动识别常见格式,封装线程安全的解析器。
立即学习“Java免费学习笔记(深入)”;
使用场景:日志里混着"2024-03-15"、"2024/03/15 14:22:33"、"15-Mar-2024"等多种格式,不想写一堆try-catch。
-
DateTimeUtil.parse("2024-03-15 14:22:33")→ 自动匹配yyyy-MM-dd HH:mm:ss -
DateTimeUtil.parse("15/03/2024", "dd/MM/yyyy")→ 显式指定格式,避免歧义 -
DateTimeUtil.offsetDay(dateTime, 7)→ 比plusDays(7)更直白,且支持负数偏移
性能影响小,内部缓存了常用DateTimeFormatter实例;但别用它替代业务强校验——比如“必须是工作日”,还得自己加逻辑。
JSON解析写到吐?JSONUtil直接转Bean,不碰ObjectMapper配置
Spring Boot项目里ObjectMapper常要配SerializationFeature、DeserializationFeature,一换环境就反序列化失败;纯工具类又懒得引Jackson。Hutool的JSONUtil默认关闭严格模式,能兼容字段名大小写、下划线转驼峰、空值跳过等现实场景。
常见错误现象:JSONUtil.toBean(jsonStr, User.class)报JSONException,大概率是字段类型不匹配(比如JSON里是"age": "25"但Java字段是int),而不是语法错误。
-
JSONUtil.parseObj(jsonStr)→ 返回JSONObject,类似Map,适合动态结构 -
JSONUtil.toBean(jsonStr, User.class)→ 支持构造器注入、忽略未知字段、自动类型转换("true"→boolean) -
JSONUtil.toJsonStr(obj)→ 默认不缩进、不转义HTML字符,如需美化用JSONUtil.toJsonStr(obj, JSONConfig.create().setPretty(true))
兼容性注意:它底层可选Jackson或Gson,但默认用自己轻量实现;如果项目已重度依赖Jackson注解(如@JsonAlias),JSONUtil不识别,得切回原生方案。
文件上传下载总卡在IO流?FileUtil和StreamUtil包圆基础操作
写个文件复制还要记Files.copy的StandardCopyOption参数,上传临时文件后忘了deleteOnExit(),下载时没设Content-Disposition导致浏览器乱打开——这些琐事FileUtil和StreamUtil全兜了。
使用场景:后台接收MultipartFile后存本地,或从HTTP URL拉取资源保存到磁盘。
-
FileUtil.writeUtf8String("hello", "/tmp/test.txt")→ 自动创建父目录,覆盖写入 -
FileUtil.copy(file, new File("/backup/" + file.getName()), true)→ 第三个参数true表示覆盖 -
StreamUtil.readUtf8(new URL("https://api.example.com/data").openStream())→ 一行读完远程文本,不用关流
容易踩的坑:FileUtil路径分隔符默认用/,Windows下传"C:\data\test.txt"会失败,得写成"C:/data/test.txt"或用FileUtil.file("C:", "data", "test.txt")拼接。
真正麻烦的从来不是单点功能,而是格式不一致、边界不统一、异常不收敛——Hutool的价值不在“多”,而在把散落在各处的if、try、new SimpleDateFormat这些噪音,压进一个命名清晰的静态方法里。用之前扫一眼源码里的@since和@deprecated标记,有些方法在新版本里已经转向更严格的语义了。










