那天晚上加班写个小工具,本来就几行代码的事,结果同事在旁边看着我写try-catch写得一脸懵,说:“你这玩意儿 JDK17 一行搞定啊,还写半天。” 我当时心里一动,这不就是那种——你以为你写的是业务,其实你写的是历史遗产——的瞬间吗。
老JDK的「啰嗦时代」
以前写 Java,尤其是 JDK8 那会儿,真的是——“啰嗦是美德”。举个例子,比如我想读取个文件,然后打印每一行大写形式:
try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line.toUpperCase());
}
} catch (IOException e) {
e.printStackTrace();
}
十行起步,写完手都酸。更别说null判空、流关闭、异常嵌套这些锅,统统得自己背。 那时候 IDE 还挺喜欢跟你较劲,光是补全catch块就能弹出十几个提示。
新时代的“一行党”崛起
到了 JDK17,真的变了。 同样的逻辑,我现在写成这样:
Files.lines(Path.of("data.txt")).map(String::toUpperCase).forEach(System.out::println);
完了。 不光完了,还更安全,Files.lines()自带自动关闭流的机制,也不会出现资源泄漏。 这行代码里,map、forEach、Path.of这些 API 在 JDK11 到 JDK17 都陆续进化过,背后是整个 IO、Stream API、NIO 的融合。
你说,这差距是不是有点像「写for循环」和「写SQL」的区别?
模式匹配让 if 变得优雅
以前你写类型判断,是不是都是这种风格?
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
现在 JDK17 直接告诉你:你可以不转型,但我可以。
if (obj instanceof String s) {
System.out.println(s.length());
}
语法糖虽然小,但这种“把语义拉直”的感觉,是真的爽。尤其配合switch模式匹配,那种原地重构的快乐,堪比去掉if else的第一天。
Record,让 DTO 变回“数据对象”
以前写 DTO 类,就像搬砖:
public class User {
private final String name;
private final int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String name() { return name; }
public int age() { return age; }
}
JDK17 直接一行结束战斗:
record User(String name, int age) {}
它天然带构造、getter、toString()、equals()、hashCode(),完美符合“只是个数据载体”的场景。 以前写 10 行,现在写 1 行。你说我为啥还得老守着旧写法?
Text Blocks:告别那些拼接的痛苦
以前想写个 JSON 模板,简直是视觉灾难:
String json = "{\n" +
" \"name\": \"" + name + "\",\n" +
" \"age\": " + age + "\n" +
"}";
现在你只要三引号:
String json = """
{
"name": "%s",
"age": %d
}
""".formatted(name, age);
可读性和可维护性直接飞升。 前几年写 Spring Boot 模板邮件时,要是有这玩意儿,少说能省一半的眼泪。
var 和 sealed class:语义更近人
有同事老说:“var会让类型不清晰。” 我笑了。你看看这句:
var map = new HashMap<String, List<Integer>>();
这不是比Map<String, List<Integer>> map = new HashMap<>();一眼清爽多了? 类型在右边,语义足够明显,谁还嫌看不懂?反而逻辑更聚焦。
再看sealed class,一招封印继承范围:
sealed interface Shape permits Circle, Rectangle {}
final class Circle implements Shape {}
final class Rectangle implements Shape {}
用在 SDK、框架里,避免外部乱继承滥扩展,堪称 API 设计的安全锁。
那我还要 JDK8 干嘛?
说句实话——要不是历史包袱,谁还真愿意守着老版本?
但是话说回来,企业用 JDK8 不只是“懒”,更多是“稳”。很多依赖库只测到 8,部分容器还默认跑在老版本的 JVM 上。 可现在 JDK17 已经是 LTS(长期支持),JDK21 也在路上,迁移的成本其实越来越低。
所以,我现在的做法是—— 新项目一律 17 起步,老项目就别硬抬了。 等哪天要重构模块时,就像搬家一样,顺带把 Java 版本也升上去。
写在最后
说到底,语言进化的目标不是让你少打字,而是让你少分心。 JDK8 让 Java 不再古板,JDK17 让 Java 回归简洁。 从“写十行才能说一句话”,到“一行就能表达意图”,这是 Java 真正的成熟。
有点像我们写了多年业务代码后才懂得的那个道理:能写少的,不一定是偷懒,而是终于理解了。