03-JDK 10/11 局部变量推断与 LTS:var 到底该怎么用

JDK 9 之后,Oracle 改了发布节奏:从"几年一个大版本"变成"每半年一个功能版"(3 月、9 月各一版)。于是 JDK 10(2018-03)、JDK 11(2018-09)紧跟着来。这两版单体特性不多,但有两个影响深远的东西:var 局部变量推断 ,以及 LTS(长期支持版)制度的确立------后者直接决定了你公司"升到哪、停在哪"。


一、var:类型推断,不是动态类型

JDK 10 最显眼的特性就是 var。它让编译器根据右边的初始值推断变量类型,你不用再写出来:

java 复制代码
// 以前
ArrayList<User> users = new ArrayList<>();
Map<String, List<Integer>> map = new HashMap<>();

// JDK 10+
var users = new ArrayList<User>();
var map = new HashMap<String, List<Integer>>();

但务必澄清一个误解:var 不是 JavaScript 那种动态类型 。var 只是"让我少打几个字",变量类型在编译期就确定了,是强类型、不可变类型。下面这样会编译失败:

java 复制代码
var x = 10;
x = "hello";   // 编译错误:x 已被推断为 int

var 的边界(哪里能用、不能用)

能用 不能用
局部变量(有初始化) 方法参数、返回值、字段
for 循环变量 没有初始化表达式(var x;)
try-with-resources 资源 lambda 参数(JDK 11 起 lambda 参数可隐式类型,但不用 var 关键字)
增强 for 迭代变量 数组初始化器(var a = {1,2} 不行,类型不明)

什么时候该用 var,什么时候不该

经验法则:var 提升可读性就用,损害可读性就不用。

  • 类型在右手一目了然时(构造器、List.of),用 var 更清爽。
  • 类型不明显时(方法返回值、魔法数字 var x = compute()),老老实实写类型,否则读代码要回跳找声明。
java 复制代码
var list = new ArrayList<String>();   // 好:类型一眼看出
var result = service.query();          // 差:得去查 query 返回啥

二、LTS 制度:为什么"升到 11 还是 8"是个真问题

这是 JDK 10/11 里比 var 重要十倍的事。Oracle 的新规则:

  • 每 6 个月一个功能版 ,但只有每三年一个版本是 LTS(Long-Term Support),会得到多年的安全与 bug 修复。
  • JDK 8 是事实上的 LTS(虽早于此制度,但长期维护)。
  • JDK 11 是第一个按新制度发布的 LTS,接着是 17、21......
  • 非 LTS 版本(10、12、13、14、15、16、18、19、20 等)只有半年支持,很快 EOL。

这意味着企业升级策略变成:在 LTS 之间跳跃(8 → 11 → 17 → 21),而不是追每个小版本。选 LTS 的理由是------云厂商、Spring、中间件都只对 LTS 做充分验证;选非 LTS 等于自己当小白鼠。

一句话决策:生产系统优先盯 LTS。2026 年的今天,新项目起点建议 21(最新 LTS);老系统至少升到 17。


三、JDK 11 的其他硬货

JDK 11 作为 LTS,攒了不少实用特性:

1. 单文件源码直接运行

不用先 javac 再 java,直接 java Hello.java 就能跑(编译器在内存里编译后执行)。小脚本、教学 demo 省一步。

2. 全新的 HTTP 客户端(转正)

JDK 9 孵化的 jdk.incubator.http 在 11 转正为 java.net.http,支持 HTTP/2、WebSocket,API 比老 HttpURLConnection 现代得多:

java 复制代码
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/user"))
    .header("Accept", "application/json")
    .build();
HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.statusCode() + " -> " + resp.body());

// 异步也很自然
client.sendAsync(req, HttpResponse.BodyHandlers.ofString())
    .thenApply(HttpResponse::body)
    .thenAccept(System.out::println);

3. 字符串增强

java 复制代码
"  hello  ".strip();        // 去首尾空白(识别 Unicode 空白,比 trim 更准)
"  hello  ".stripIndent();  // 去公共缩进(配合文本块,见 12/13 篇)
"a".repeat(3);              // "aaa"
"java".isBlank();           // false;"  ".isBlank() true(全空白判断)

4. 集合与 Optional 小补

  • List.of / Set.of / Map.of 在 9 引入,11 稳定。
  • Optional 加 isEmpty()、ifPresentOrElse、or、stream()。
  • String 底层完成紧凑化:纯 Latin-1 字符用 1 字节存,内存直接省一半(9 引入,11 打磨)。

5. 性能与 GC

  • ZGC(实验) 和 Epsilon(无操作 GC) 引入:ZGC 目标亚毫秒停顿、支持超大堆;Epsilon 用于测试/极短生命周期场景。
  • G1 持续调优,成为实至名归的默认主力。

6. 移除了什么

JDK 11 删掉了 Java EE 和 CORBA 模块 (java.xml.bind 等 JAXB 被移除),也删了 javafx(改由 OpenJFX 独立维护),还去掉了 Nashorn JavaScript 引擎(后续版彻底移除)。这意味着老项目如果从 JDK 8 升级到 11,若用到 javax.xml.bind 等,必须手动加第三方依赖(如 jakarta.xml.bind),这是迁移第一大坑。


四、本篇记住的清单

  1. var 是编译期类型推断,仍是强类型,不能用于参数/返回值/字段。
  2. var 提升可读性就用,类型不明时老实干写类型。
  3. LTS 制度:8/11/17/21 是 LTS;企业只在 LTS 间跳跃升级。
  4. JDK 11 可 java X.java 直接跑单文件源码。
  5. java.net.http 全新 HTTP 客户端,支持 HTTP/2 与异步。
  6. 字符串 strip/isBlank/repeat 比 trim 更现代。
  7. JDK 11 移除 JAXB/CORBA/JavaFX/Nashorn------8 升 11 迁移的第一类雷。
  8. ZGC、Epsilon 在 11 进场(实验)。

理解了 var 和 LTS,你就掌握了"现代 Java 升级节奏"的开关。下一篇 JDK 12/13:var 之后,文本块和 switch 表达式又让代码清爽了一截。

相关推荐
Percep_gan2 小时前
调用天翼云的对象存储ZOS,很详细
java·1024程序员节
若亦_2 小时前
数据结构>>优先级队列(堆)
java·数据结构
Wang's Blog2 小时前
Java 项目实战: 交友项目 - 查询圈子个人动态:查询我的动态需求分析
java·开发语言·交友
denlaku2 小时前
JDK 23 新特性详解
java
code2cat2 小时前
Java高级篇之Hibernate:让对象映射到表,理解持久化与事务
java·后端·hibernate·1024程序员节
骑着蜗牛撵大象3273 小时前
飞牛fnOS部署Damselfly:Compose编排、照片目录与7100固定访问
java·docker·rpc·dubbo·fnos·照片管理·damselfly
金銀銅鐵3 小时前
[Java] 用 CLI 展示 EnumSet 增减元素时的内部变化(下)
java·后端·ai编程
Nuanyt4 小时前
Hot 100 刷题笔记 · 数组与哈希专题(3 题)
java·笔记·算法·leetcode·哈希算法·1024程序员节
xieliyu.4 小时前
【JavaEE进阶】Spring Boot 日志:从 System.out 到 @Slf4j,6 个级别 + 4 类配置一篇讲透
java·spring boot·spring·java-ee·springboot·logback·slf4j