测试环境:Oracle JDK 26.0.2+10-55(2026-07-21 构建),Windows 11 实机编译运行。文中所有代码与输出均为真实执行结果,非虚构。Java 26 于 2026-03-17 发布,共 10 个 JEP(来源:OpenJDK、happycoders.eu Java 26 Features)。
Java 26 不是一个大版本。没有新语法糖轰炸,也没有颠覆性架构。但这一版有个鲜明特征:还债。还反射破坏 final 的债、还 HttpClient 不支持 HTTP/3 的债、还 switch 对原始类型爱答不理的债。本文挑 4 个最值得关注的 JEP 逐一拆解,并附上实机跑出的输出。
一、新特性学习
1.1 JEP 526:Lazy Constants(第二次预览)—— Stable Values 改名重来
Java 25 里这个特性叫Stable Values(JEP 502)。一年预览期收到反馈后,Java 26 把它推倒重做并改名Lazy Constants(JEP 526,作者 Per Minborg & Maurizio Cimadamore,OpenJDK 官方文档)。
它解决什么问题?final字段只能在类加载或对象构造时初始化。如果你想"用到才初始化",过去只能手写 double-checked locking 或者 initialization-on-demand holder 惯用法——两种都容易写错。
Lazy Constants 的核心 API 就三行:
// Java 26 preview(需 --enable-preview)privatestaticfinalLazyConstant<Settings>CONFIG=LazyConstant.of(()->loadSettingsFromDatabase());Settingss=CONFIG.get();// 首次调用触发初始化,之后永远返回同一个值线程安全由 JDK 保证:多线程同时首次get(),初始化函数最多执行一次。初始化完成后,JVM 把它当成真正的常量做 constant folding——这是普通懒加载单例拿不到的性能红利。
Java 26 相对 Java 25 的关键变化(来源:JEP 526 History 一节):
| 变化 | 说明 |
|---|---|
改名StableValue→LazyConstant | 从底层机制命名改为面向用例命名 |
删除orElseSet/setOrThrow/trySet | 低层 API 砍掉,只留接收计算函数的高层工厂方法 |
| 懒集合工厂搬家 | List.ofLazy(...)、Map.ofLazy(...)直接挂在List/Map接口上 |
| 禁止 null 值 | 计算函数返回 null 直接抛NullPointerException |
注意:如果你已经在 Java 25 上用了 Stable Values,升级到 26 需要不小的重构。
1.2 JEP 530:原始类型进 Patterns / instanceof / switch(第四次预览)
switch 支持原始类型不是新闻——但过去只支持byte/short/char/int,且 case 标签只能是常量。JEP 530(Owner: Angelos Bimpoudis)把门彻底打开:所有原始类型都能进switch和instanceof,还能带模式变量和 guard。
最有意思的语义是"最小类型匹配"。对double做 switch,case 从byte到double排列时,值会落入能无损表示它的最小类型:
doublevalue=42;switch(value){casebyteb->...// 42 命中这里casecharc->...caseinti->...casedoubled->...}Java 26 还加强了 dominance 检查:Java 25 能编译通过的三类 switch(常量被更宽模式支配、模式被前置模式完全覆盖等),Java 26 编译器直接报错。更严格,但能在编译期逮住更多死代码。
1.3 JEP 517:HttpClient 原生支持 HTTP/3
HTTP/3(基于 QUIC,IETF 2022 年标准化)早已是浏览器标配,约三分之一网站部署(w3techs 数据,JEP 517 引用)。但 Java 的 HttpClient 一直停在 HTTP/2。Java 26 补上了,且设计得很克制:
- 默认协议不变,仍是 HTTP/2,HTTP/3 必须显式 opt-in;
- 客户端级别或单个请求级别都可开启;
- 服务器不支持 HTTP/3 时透明回退 HTTP/2;
- 不提供 QUIC 协议本身的 API,不做服务端实现(JEP 517 Non-Goals)。
HttpClientclient=HttpClient.newBuilder().version(HttpClient.Version.HTTP_3)// opt-in.build();1.4 JEP 500:让 final 真的 final(第一步:警告)
这可能是影响面最大的一个。final字段其实可以被深反射随意改写(Field.setAccessible(true)然后set),这让 JVM 不敢对实例 final 字段做激进的常量折叠,也让"不可变"承诺形同虚设。
Java 26 迈出第一步:反射修改 final 字段时打印 WARNING。未来版本默认抛IllegalAccessException,除非用--enable-final-field-mutation=<module>显式放行。过渡期可用 VM 选项预演未来行为:
| 选项 | 行为 |
|---|---|
--illegal-final-field-mutation=allow | 无警告(Java 26 之前的默认) |
--illegal-final-field-mutation=warn | 首次修改时警告(Java 26 默认) |
--illegal-final-field-mutation=debug | 每次修改都警告 |
--illegal-final-field-mutation=deny | 直接抛IllegalAccessException(未来默认) |
1.5 其余变化速览
- JEP 522 G1 吞吐优化:引入第二张 Card Table,优化线程与应用线程不再互相等待,吞吐量提升 5–15%,代价仅 0.2% 额外 native 内存。升级即生效,零配置。
- JEP 516 AOT 对象缓存支持任意 GC:Java 24 引入的 AOT 缓存此前与 GC 绑定(G1 建的缓存 ZGC 读不了),Java 26 引入 GC 无关的 “Streamable Objects” 格式,ZGC、大堆(>32GB)、关闭 Compressed Oops 场景通用。
- JEP 504 移除 Applet API:2017 年弃用、2022 年标记移除,九年之后正式删除。
Thread.stop()也一并删除——这个方法 1998 年就被 deprecated,拖了 27 年。 - 杂项:Unicode 17.0 支持、Javadoc 暗色主题、默认初始堆从物理内存 1/64 降到 1/500(64GB 机器上 Hello World 不再上来就占 1GB 堆,JDK-8348278)、
BodyPublishers.ofFileChannel流式上传大文件。
二、新特性小 Demo(实机输出)
测试机:Windows 11,Oracle JDK 26.0.2(java version "26.0.2" 2026-07-21,build 26.0.2+10-55)。
Demo 1:Lazy Constants + 原始类型模式匹配(Java 26 preview)
// Java26Demo.java —— 编译: javac --release 26 --enable-preview Java26Demo.javaimportjava.lang.LazyConstant;importjava.util.List;importjava.util.Map;importjava.util.Set;publicclassJava26Demo{// JEP 526: 模拟昂贵的配置加载,首次 get() 才触发privatestaticfinalLazyConstant<String>CONFIG=LazyConstant.of(()->{System.out.println(" [触发] loadSettingsFromDatabase() 被执行了!");return"theme=dark, lang=zh-CN, region=CN";});// Lazy List: 每个元素按需初始化(索引×100 的平方根)privatestaticfinalList<Double>SQRTS=List.ofLazy(5,i->Math.sqrt(i*100));// Lazy Map: 每个 key 对应的值按需计算privatestaticfinalMap<String,Integer>NAME_LENGTHS=Map.ofLazy(Set.of("Python","Java","Rust"),String::length);publicstaticvoidmain(String[]args){System.out.println("=== JDK "+Runtime.version()+" ===");System.out.println("第一次 get(): "+CONFIG.get());System.out.println("第二次 get(): "+CONFIG.get());System.out.println("SQRTS.get(2) = "+SQRTS.get(2));System.out.println("SQRTS.get(4) = "+SQRTS.get(4));System.out.println("NAME_LENGTHS.get(\"Java\") = "+NAME_LENGTHS.get("Java"));// JEP 530: primitive 类型进 switch 模式,值落入能无损表示它的最小类型double[]samples={42,50_000,100_000,0.5,0.7};for(doublevalue:samples){Stringmatched=switch(value){casebyteb->"byte "+b;casecharc->"char "+(int)c;caseinti->"int "+i;caselongl->"long "+l;casefloatf->"float "+f;casedoubled->"double "+d;};System.out.println(" "+value+" -> "+matched);}// JEP 530: primitive 模式 + guard 范围检查intcode=404;Stringkind=switch(code){caseinti when i>=200&&i<300->"success";caseinti when i>=400&&i<500->"client error";caseinti when i>=500&&i<600->"server error";default->"other";};System.out.println("HTTP "+code+" -> "+kind);}}实机输出(JDK 26.0.2+10-55,一字未改):
=== JDK 26.0.2+10-55 === [触发] loadSettingsFromDatabase() 被执行了! 第一次 get(): theme=dark, lang=zh-CN, region=CN 第二次 get(): theme=dark, lang=zh-CN, region=CN SQRTS.get(2) = 14.142135623730951 SQRTS.get(4) = 20.0 NAME_LENGTHS.get("Java") = 4 42.0 -> byte 42 50000.0 -> char 50000 100000.0 -> int 100000 0.5 -> float 0.5 0.7 -> double 0.7 HTTP 404 -> client error三个看点:初始化函数只执行了一次(第二次get()前没有再打印"[触发]");50000落入char而非int——因为 char 能无损表示它且排在 int 前面;0.5能用 float 精确表示所以匹配 float,0.7不行(float 无法无损表示 0.7),落到 double。类型匹配的精度语义非常讲究。
Demo 2:HTTP/3 实战(JEP 517)
// Http3Demo.java —— 编译: javac Http3Demo.java(无 preview 依赖)HttpClientclient=HttpClient.newBuilder().version(HttpClient.Version.HTTP_3).connectTimeout(Duration.ofSeconds(15)).build();HttpRequestrequest=HttpRequest.newBuilder(URI.create("https://www.cloudflare.com/")).version(HttpClient.Version.HTTP_3).GET().build();HttpResponse<String>response=client.send(request,HttpResponse.BodyHandlers.ofString());System.out.println("status="+response.statusCode()+" 实际协议="+response.version());实机输出:
https://www.cloudflare.com/ status=200 实际协议=HTTP_3 耗时=21495ms body长度=1304602 https://www.happycoders.eu/ status=200 实际协议=HTTP_3 耗时=566ms body长度=124414response.version()返回HTTP_3,证明 QUIC 协商成功,不是回退。第一个目标耗时 21 秒多,是首次 HTTP/3 连接的 QUIC 握手 + 路径 MTU 探测叠加了公司网络环境的干扰;第二个目标 566ms 属于正常水平。生产上建议对 HTTP/3 客户端做连接池复用,避免反复付握手成本。
Demo 3:JEP 500 警告与"未来已来"的 deny 模式
// FinalWarning.java —— 编译: javac FinalWarning.javastaticclassBox{privatefinalStringvalue;Box(Stringvalue){this.value=value;}@OverridepublicStringtoString(){return"Box{value="+value+"}";}}Boxbox=newBox("Rubik's Cube");Fieldf=Box.class.getDeclaredField("value");f.setAccessible(true);f.set(box,"Magic Wand");// Java 25 静默通过;Java 26 起打 WARNING默认运行(warn 模式)输出:
before: Box{value=Rubik's Cube} WARNING: Final field value in class FinalWarning$Box has been mutated reflectively by class FinalWarning in unnamed module @15db9742 (file:/D:/hermes_win/hermes_work/temp/jdk26_dl/demo/) WARNING: Use --enable-final-field-mutation=ALL-UNNAMED to avoid a warning WARNING: Mutating final fields will be blocked in a future release unless final field mutation is enabled after: Box{value=Magic Wand}加上--illegal-final-field-mutation=deny再跑,就是未来 Java 版本的默认行为:
Exception in thread "main" java.lang.IllegalAccessException: class FinalWarning (in unnamed module @15db9742) cannot set final field FinalWarning$Box.value (in unnamed module @15db9742), unnamed module @15db9742 is not allowed to mutate final fields at java.base/java.lang.reflect.Field.preSetFinal(Field.java:1504) at java.base/java.lang.reflect.Field.setFinal(Field.java:1447) at java.base/java.lang.reflect.Field.set(Field.java:909) at FinalWarning.main(FinalWarning.java:26)依赖反射改 final 的库(某些序列化框架、mock 框架的早期实现)现在就该自查了,别等未来版本默认 deny 时生产炸雷。
三、排名与热度长远分析
3.1 现状:稳居前四,份额微跌
TIOBE 2026 年 7 月榜单:Java 以8.03%份额位居第 4,同比微跌 0.73 个百分点。前面是 Python(18.94%)、C(10.86%)、C++(9.12%),后面是 C#(4.49%)——Java 与第 5 名拉开近一倍身位,与第 3 名 C++ 的差距约 1 个百分点(来源:tiobe.com/tiobe-index)。
3.2 三十年轨迹:从第 22 名到三冠王,再让出头名
TIOBE 官方历史排名表给出的 Java 轨迹:
| 年份 | 1996 | 2001 | 2006 | 2011 | 2016 | 2021 | 2026 |
|---|---|---|---|---|---|---|---|
| Java 排名 | 22 | 3 | 1 | 1 | 1 | 2 | 4 |
1996 年 TIOBE 榜单上 Java 只排第 22,五年后冲进前三,随后在 2006、2011、2016 三个年度快照中登顶,并拿下 2015 年 TIOBE 年度语言。2021 年起 Python 坐上头把交椅并保持至今(2026 年 7 月 18.94%),Java 逐步退居第四。
但要泼一盆冷水:TIOBE 统计的是搜索引擎命中数,反映的是"讨论热度"而非生产环境使用量。另一组数据更接近真相:Stack Overflow 2025 开发者调查中 Java 使用率约 29%,被该榜单归类为 “Enterprise backbone”;index.dev 按自有方法统计的 2026 年 4 月榜单里 Java 排第 3(10.66%,同比 +1.79%)。榜单在跌,基本盘没动。
3.3 同梯队对比与未来两年预测
第一梯队(Python/C/C++/Java)内部,Java 的护城河是企业后端、Android、大数据(Hadoop/Spark/Flink 生态)和金融核心系统。它和第 5 名 C# 的差距(8.03% vs 4.49%)远大于与第 3 名 C++ 的差距,短期内前四席位稳固。真正的威胁不是榜单上的语言,而是 Kotlin 在 Android 生态的持续替代,以及 Go 在云原生中间件领域的蚕食。
Java 的反击筹码恰好在这两年的路线图里:虚拟线程(Java 21 正式化)正在改变 Java 在云原生高并发场景的口碑;JEP 516/522 这类启动速度和 GC 吞吐优化直指 Serverless 痛点;Project Valhalla 的 value classes 早期访问版已在 2025 年 10 月放出(jdk.java.net/valhalla)。
预测:未来 1-2 年 Java 在 TIOBE 大概率维持第 3-5 名震荡。若 Valhalla 正式落地且虚拟线程生态(Spring、Quarkus 等)持续收割存量迁移,有望在 2027-2028 年与 C++ 争夺第 3。跌出前五的可能性极低——除非 Python 式的"AI 单一变量冲击"在企业后端重演,而这个领域目前没有替代品。
四、本周总结
Java 26 是一个"工程师友好"的版本:
- Lazy Constants(JEP 526)把线程安全的懒初始化变成一行 API,还附送 constant folding 性能红利——第二次预览,API 已大幅收敛,值得在新项目里试用;
- HTTP/3(JEP 517)让 HttpClient 跟上 2022 年的协议标准,opt-in 设计不打扰存量代码,实测 QUIC 协商一次成功;
- 原始类型模式匹配(JEP 530)第四次预览,"最小类型匹配"语义精巧,dominance 检查收紧能在编译期多逮 bug;
- JEP 500 的 final 警告是最需要重视的迁移信号——现在排查,好过未来版本被动挨炸;
- 排名层面,Java 在 TIOBE 第 4(8.03%)微跌,但企业使用量基本盘(约 29% 开发者)纹丝不动,虚拟线程 + Valhalla 是未来两年最大的排名变量。
一句话:Java 26 没有惊喜,但没有废话。该升级的升级,该排查 final 反射的排查。
参考资料
- JEP 526: Lazy Constants (Second Preview) — openjdk.org/jeps/526
- JEP 530: Primitive Types in Patterns, instanceof, and switch (Fourth Preview) — openjdk.org/jeps/530
- JEP 517: HTTP/3 for the HTTP Client API — openjdk.org/jeps/517
- JEP 500: Prepare to Make Final Mean Final — openjdk.org/jeps/500
- Java 26 Features (with Examples) — happycoders.eu/java/java-26-features(2026-06-12 更新)
- TIOBE Index — tiobe.com/tiobe-index(2026 年 7 月榜单)
- C# wins TIOBE Programming Language of the Year honors for 2025 — InfoWorld(2026-01-05)
- Programming Language Statistics 2026 — rockstardeveloperuniversity.com(Stack Overflow / RedMonk 汇总)
所有代码在 Oracle JDK 26.0.2+10-55(Windows 11)实机编译运行,输出未经修饰。Preview 特性编译运行需加--enable-preview。