Java全版本特性与用法示例(含总览 + 分版本要点)
本文按 正式发布的 JDK / Java SE 大版本 罗列:自 JDK 1.0(1996) 起,至 Java 26(2026-03,当前时间线内已发布);文末附 类文件主版本号 与 编译参数。具体行为以你使用的 发行版(OpenJDK/Oracle/…)的 Release Notes 为准。
命名习惯: 对外常称 Java 8、Java 17;开发者版本号可能仍写 1.8、1.17(9 起模块系统后较少混用 1.9)。
发布节奏(2017 年 9 月起): 大版本约 每 6 个月 一次;LTS 由 Oracle/OpenJDK 路线约定,常见 LTS 为 8、11、17、21、25(以官方为准)。
每节“正式特性”示例的约定: 自 该版本号 起,下列代码块展示 默认即可编译、不依赖 --enable-preview 的正式语言或标准库能力;若该版仅有预览/工程类变更,则在该节单独说明,并改用 自较早版本起已稳定、且与当年发行说明仍兼容 的库或 JVM 接口示例(不冒充“新 正式 语法”)。
0. 全版本总览表
| 版本 | 常记名 | 类文件主版本 | 约首发日期 | 备注 |
|---|---|---|---|---|
| JDK 1.0 | Java 1 | 45 | 1996-01 | 首版 |
| JDK 1.1 | 45 | 1997-02 | ||
| J2SE 1.2 | Java 2 | 46 | 1998-12 | “Java 2” 品牌、集合、Swing… |
| J2SE 1.3 | 47 | 2000-05 | ||
| J2SE 1.4 | 48 | 2002-02 | assert、NIO、正则… | |
| J2SE 5.0 | Java 5 | 49 | 2004-09 | 泛型、枚举、注解… |
| Java SE 6 | 50 | 2006-12 | 从此对外称 Java SE | |
| Java SE 7 | 51 | 2011-07 | try-with-resources、 diamond… | |
| Java SE 8 | LTS | 52 | 2014-03 | Lambda、Stream、java.time |
| Java SE 9 | 53 | 2017-09 | 模块、JShell… | |
| Java SE 10 | 54 | 2018-03 | var | |
| Java SE 11 | LTS | 55 | 2018-09 | 标准 HttpClient 等 |
| Java SE 12 | 56 | 2019-03 | ||
| Java SE 13 | 57 | 2019-09 | ||
| Java SE 14 | 58 | 2020-03 | ||
| Java SE 15 | 59 | 2020-09 | ||
| Java SE 16 | 60 | 2021-03 | ||
| Java SE 17 | LTS | 61 | 2021-09 | 密封类、switch 模式预览演进 |
| Java SE 18 | 62 | 2022-03 | 默认 UTF-8 等 | |
| Java SE 19 | 63 | 2022-09 | 虚拟线程预览等 | |
| Java SE 20 | 64 | 2023-03 | 多为预览/孵化 | |
| Java SE 21 | LTS | 65 | 2023-09 | 虚拟线程正式、模式匹配等 |
| Java SE 22 | 66 | 2024-03 | FFM API 等 | |
| Java SE 23 | 67 | 2024-09 | 撤 String Templates 预览等 | |
| Java SE 24 | 68 | 2025-03 | 安全点:Security Manager 等 | |
| Java SE 25 | LTS | 69 | 2025-09 | 模块 import、简洁入口等定稿 JEP 见发行说明 |
| Java SE 26 | 70 | 2026-03 | HTTP/3 客户端、移除 Applet API 等 | |
| Java SE 27 | 计划 | 71 | 2026-09 | 路线图,以官方为准 |
说明: 表中 Java SE 27 在 尚未 GA 时,本文不虚构其「新终态」语法;在 GA 后应以 JEP 与发行说明 为准增补对应小节。其余已 GA 大版本在下方各节均至少给出一个 不依赖 --enable-preview 的「正式能力」 例(§21 等以 JEP 为预览为主 的版本单独说明,并附 JFR/既有 API 等 的正式用例作为替代)。
1. JDK 1.0(1996)
- 核心语言与
java.lang/java.util基础类。 - AWT 图形、Applet、基础 I/O 与网络。
示例:典型古老写法(无泛型、无 main 参数短路):
public class Hello {
public static void main(String[] args) {
System.out.println("Hello");
}
}
2. JDK 1.1(1997)
- 内部类、JDBC、RMI 与序列化、JavaBeans。
- 反射(以自省为主,运行期可修改能力在后续版本加强)。
- AWT 事件模型大改、国际化与 Unicode。
正式 1.1:内部类 + JDBC 最简“可连接”形态(DriverManager 在 1.1 中引入,URL/驱动以你环境为准):
// JDBC 1.0 起:用反射加载驱动是常见写法
// Class.forName("org.example.Driver");
// java.sql.Connection c = java.sql.DriverManager.getConnection("jdbc:...");
正式 1.1:非静态内部类可访问外部实例:
class Outer {
class Inner { void f() { System.out.println(Outer.this); } }
}
3. J2SE 1.2 / “Java 2”(1998)
- 集合框架(
List/Map/Set等)、strictfp、Swing、Java 插件、Java IDL(CORBA)、首版广泛 JIT(HotSpot 路线起点)。
正式 1.2:集合 + Iterator(无泛型版本):
import java.util.*;
List list = new ArrayList();
list.add("a");
for (Iterator it = list.iterator(); it.hasNext(); ) {
String s = (String) it.next();
}
Map map = new HashMap();
map.put("k", "v");
正式 1.2:Swing 顶层窗口最小骨架:
import javax.swing.JFrame;
import javax.swing.JLabel;
// JFrame f = new JFrame(); f.getContentPane().add(new JLabel("ok")); f.pack(); f.setVisible(true);
4. J2SE 1.3(2000)
- HotSpot VM 进入主线、JNDI 入核心、JavaSound、JPDA、RMI 与 CORBA 互操作加强、动态代理类。
正式 1.3:动态代理 Proxy + InvocationHandler(无 Lambda,用匿名类):
import java.lang.reflect.*;
interface I { int run(); }
class H implements InvocationHandler {
public Object invoke(Object p, Method m, Object[] a) { return 1; }
}
// I r = (I) Proxy.newProxyInstance(I.class.getClassLoader(), new Class[]{I}, new H);
5. J2SE 1.4(2002,JSR 59)
- 语言:
**assert**。 - 库:正则、
java.util.logging、NIO(阻塞/选择器)、异常链、IPv6、JAXP、安全与加密封装、Image I/O、Web Start、Preferences。
正式 1.4:断言 assert(默认关闭,运行 用 java -ea … 开启):
class A4 {
void m(int x) {
assert x >= 0 : "x must be non-negative";
}
}
6. Java SE 5.0 / 1.5(2004,Tiger)
- 泛型、注解、枚举、自动装箱/拆箱、变长参数、for-each、静态 import、
java.util.concurrent、内存模型修订。
import java.util.*;
enum Day { MON, TUE }
List<String> list = new ArrayList<String>();
for (String s : list) { }
void foo(int... xs) { }
7. Java SE 6 / 1.6(2006)
- 脚本(JSR 223,内置 Rhino)、JAX-WS 2.x、JDBC 4.0、编译器 API、Pluggable Annotations、Swing 与 JVM/ GC 性能、JAXB 2.0 等。
正式 6:JSR 223 脚本引擎(内置 Rhino JavaScript 名依实现而定,常见为 js 或 JavaScript):
import javax.script.*;
ScriptEngine eng = new ScriptEngineManager().getEngineByName("js");
if (eng != null) {
eng.eval("1 + 2");
}
8. Java SE 7 / 1.7(2011)
try-with-resources、String可出现在switch、diamondnew ArrayList<>()、Fork/Join、Objects、Path/ NIO.2(部分在新 I/O 体系)。
import java.io.InputStream;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.*;
// try-with-resources + NIO.2
void read(Path path) throws Exception {
try (InputStream in = Files.newInputStream(path)) { /* 自动 close */ }
}
正式 7:String 的 switch、diamond、Objects、Paths:
import java.util.Objects;
import java.nio.file.Paths;
String cmd = "go";
switch (cmd) {
case "go": break;
default: break;
}
List<String> a = new ArrayList<>(); // diamond
Path p = Paths.get("a", "b", "c.txt");
Objects.requireNonNull(p, "p");
正式 7:Fork/Join 骨架:
// ForkJoinPool.commonPool() 在 1.7 引入
import java.util.concurrent.RecursiveTask;
class Sum extends RecursiveTask<Integer> { /* compute/split 省略 */ }
9. Java SE 8(2014,LTS)
- Lambda、Stream、
java.time、Optional、接口default/static、Nashorn(JS 引擎,后于更高版本移除)、重复注解、CompletableFuture等。
Lambda 与 Stream:
import java.util.*;
import java.util.stream.Collectors;
List<String> names = Arrays.asList("a", "bb", "ccc");
List<String> longOnes = names.stream()
.filter(s -> s.length() > 1)
.map(String::toUpperCase)
.collect(Collectors.toList());
接口默认方法:
interface Greeter {
default void hello() { System.out.println("Hi"); }
}
时间 API:
import java.time.*;
import java.time.format.DateTimeFormatter;
LocalDate d = LocalDate.now();
ZonedDateTime z = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
Stream 求和(Java 8 无 List.of,用 Arrays.asList):
import java.util.Arrays; int sum = Arrays.asList(1, 2, 3).stream().mapToInt(i -> i).sum();
10. Java SE 9(2017)
- Java 平台模块系统(
module-info.java)、JShell、集合工厂List.of/Set.of/Map.of、接口 private 方法、HTTP/2 客户端(孵化) 等。
module com.example.app {
requires java.base;
exports com.example.api;
}
List<String> list = List.of("a", "b");
interface Util {
private static int add(int a, int b) { return a + b; }
default int twice(int x) { return add(x, x); }
}
11. Java SE 10(2018)
- 局部变量类型推断
var、G1 全并发的部分改进、类数据共享应用面扩展等。
var list = new ArrayList<String>();
for (var s : list) { }
12. Java SE 11(2018,LTS)
- 标准
HttpClient、String增强(isBlank/lines/strip)、单文件java Hello.java直接运行、部分模块/组件从 JDK 拆出或移除(如 JavaFX/EE 曾捆绑策略变化,以发行版为准)、ZGC 实验等。
" \n".isBlank(); "line1\nline2".lines().forEach(System.out::println);
正式 11:标准 java.net.http.HttpClient(同步 GET 骨架):
import java.net.URI;
import java.net.http.*;
import java.time.Duration;
HttpClient c = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(5))
.build();
HttpRequest r = HttpRequest.newBuilder(URI.create("https://httpbin.org/get"))
.GET()
.build();
// HttpResponse<String> res = c.send(r, HttpResponse.BodyHandlers.ofString());
java Hello.java
13. Java SE 12(2019)
switch表达式(预览)、Shenandoah(实验)、微基准套、JVM 常量 API、G1/内存返还等 GC/JVM 项;String::transform(JEP 344 相关,库方法)、紧凑数字格式 等库增强。
正式 12:java.lang.constant(JEP 334,描述类文件里的常量形态):
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
ClassDesc str = ClassDesc.of("java.lang.String");
MethodTypeDesc mt = MethodTypeDesc.ofDescriptor("()V");
System.out.println(str.displayName() + " / " + mt.descriptorString());
正式 12:紧凑数字 NumberFormat(JEP 277/库增强,无需 preview):
import java.text.NumberFormat;
import java.util.Locale;
NumberFormat f = NumberFormat.getCompactNumberInstance(
Locale.CHINA, NumberFormat.Style.SHORT);
System.out.println(f.format(12_000_000)); // 显示形式依 Locale
(以下 switch 在 12 为预览;在 14 中成为正式特性,见 §15。12 中若编译需 --enable-preview):
// 预览:在 12 中需 --enable-preview;演示形态,省略 month/year 等上下文
// int days = switch (m) { case 1,3,5 -> 31; default -> 30; };
14. Java SE 13(2019)
- 文本块(预览)、
switch表达式(第二轮预览)、ZGC 归还未用内存、Socket API 重写、动态 CDS 等。
正式 13:本版无新终态 JLS 语法;下列 文本块 在 13 仍为预览(""" 需 --enable-preview)。到 15 才成为终态,例见 §16。
正式 13:标准库用法不变 的 NIO 套接字 + try-with-resources(实现已换,见 JEP 353,应用侧类型名多不变):
// 与 Java 5+ 同形态;JDK 13 中底层实现为新 Socket 实现
try (java.net.Socket s = new java.net.Socket()) {
s.connect(new java.net.InetSocketAddress("openjdk.org", 443), 5_000);
}
预览 13:二轮 switch 表达式;文本块 预览 示例(在 15 前需 preview):
// javac 13: --enable-preview
String html = """
<html>
<body>Hi</body>
</html>
""";
15. Java SE 14(2020)
switch表达式(正式,JEP 361)、instanceof模式匹配(预览)、record(预览)、文本块(二轮预览)、NPE 更可读、JFR 流式、包装工具 jpackage(孵化)、移除 CMS、ZGC 平台扩展、外部内存 API(孵化) 等。
正式 14:switch 表达式/语句 终态(JEP 361,不 再标 preview):
// Java 14+ 默认即可编译
int n = 2;
String s = switch (n) {
case 1, 2 -> "a or b";
default -> "other";
};
预览 14:模式 instanceof、record、文本块三者在 14 仍为预览/二轮(若写需当版 --enable-preview):
Object obj = "x";
if (obj instanceof String str) { System.out.println(str.length()); } // 预览
// record Point(int x, int y) { } // 预览,宜单独文件/类
String t = """
two lines
ok
"""; // 二轮 文本 预览
16. Java SE 15(2020)
- 文本块(正式)、密封类(预览)、ZGC / Shenandoah 生产可用、
instanceof模式二轮预览、record二轮预览、隐藏类、移除 Nashorn 等。
正式 15:文本块(JEP 378 终态,无需 preview):
String json = """
{
"a": 1
}
""";
System.out.println(json.stripIndent());
预览 15:密封类、记录类型与模式 instanceof 的进一步轮次在定稿上仍看 16/17;下例在 15 中多为 预览(sealed 需看当版 JEP):
// 在 16/17 前通常需按发行说明启用 preview
// public abstract sealed class Shape permits Circle, Rect { }
17. Java SE 16(2021)
record(正式)、instanceof模式(正式)、密封类二轮预览、强封装 JDK 内部(默认)、Vector API / Panama 孵化、Unix 域套接字、打包工具 等。
正式 16:record 与 模式 instanceof 终态(var 自 10 起):
public class R16 {
public record User(String name, int age) { }
public static void main(String[] args) {
var u = new User("Ann", 20);
System.out.println(u.name());
Object o = u;
if (o instanceof User x) {
System.out.println(x.age());
}
}
}
18. Java SE 17(2021,LTS)
- 密封类(正式)、强封装内部 API 强化、模式匹配 for
switch(预览)、新伪随机数 API、FFM 孵化、移实验 AOT 等、弃用 Applet 等长期路线。
正式 17:密封类型(JEP 409)+ 伪随机(JEP 356):
sealed interface Shape permits Circle, Rect { }
final class Circle implements Shape { }
final class Rect implements Shape { }
import java.util.random.RandomGenerator; RandomGenerator g = RandomGenerator.getDefault(); int n = g.nextInt(0, 10);
预览 17:对 Object 的模式 switch(至 21 终态);若用 Java 17 编译 需 javac --enable-preview:
// static String pick(Object o) { return switch (o) { case null -> "n"; case String s -> s; default -> o.toString(); }; }
19. Java SE 18(2022)
- 默认 UTF-8、简易 Web 服务器、javadoc 代码片段、反射在 MethodHandle 上重写、
switch模式匹配(二轮预览)、终结机制 Finalization 弃用 等。
正式 18:默认UTF-8 作为 Charset.defaultCharset()(JEP 400,在常见桌面/服务器 配置 上为 UTF-8;不是 改 byte[] 语义):
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
Charset d = Charset.defaultCharset();
assert StandardCharsets.UTF_8.equals(d)
|| true; // 少数配置仍可能非 UTF-8,以运行环境为准
System.out.println(d);
正式 18:JEP 408 jwebserver 提供零代码只读根目录服务(命令即「示例」;等价能力也可用 com.sun.net.httpserver 自写 HttpHandler)。
# 在含 index.html 的目录执行(需 JDK 18+ 且安装含 jwebserver 的 build) # jwebserver -p 8080
20. Java SE 19(2022)
- 虚拟线程(预览)、记录模式(预览)、
switch模式(三轮预览)、FFM(预览)、结构化并发(孵化)、RISC-V 移植等。
本版 语言/库 新增 能力多为 预览/孵化;下例 为 19 的 预览: 记录模式(javac/java 需 --enable-preview),不 作为「正式 无 preview」 示例 使用。
// javac 19: --enable-preview --release 19
class Rp19 {
record Rectangle(int x, int y, int w, int h) { }
int area(Object o) {
if (o instanceof Rectangle(int x, int y, int w, int h)) {
return w * h;
}
return 0;
}
}
正式 19(在 1.0 即存在、无 preview 的 标准库):InetAddress 等 自 18/19 起 对 点分 IPv4 文本 的解析更严格(JEP 418 行为 侧),API 名 未变。
import java.net.InetAddress;
InetAddress a = InetAddress.getByName("192.0.2.1");
System.out.println(a.getHostAddress());
21. Java SE 20(2023)
- 多为 预览/孵化(Scoped Values、Record 模式、虚拟线程、FFM、结构化并发、Vector API 等续演进)。
本大版本 JEP 列表 以 仅 预览/孵化 为主,无 新的 语言 终态 语法;正式(标准、非 preview)的 jdk.jfr 自 Java 8/9+ 起 可用。下为 JFR 录制 骨架(在 20+ 仍普遍可用、无 preview):
import jdk.jfr.FlightRecorder;
import jdk.jfr.Recording;
if (FlightRecorder.isAvailable()) {
try (Recording r = new Recording()) {
r.setName("demo");
r.setToDisk(true);
r.start();
Thread.sleep(1);
r.stop();
}
}
22. Java SE 21(2023,LTS)
- 虚拟线程(正式)、
switch模式匹配与记录模式、有序集合、分代 ZGC、KEM API 等;仍有多项 预览(String Templates、Scoped Values、结构化并发 等,后续版本有增删).
正式 21:虚拟线程 执行器、switch 模式 与 记录 模式 终态、SequencedCollection 等:
try (var ex = java.util.concurrent.Executors.newVirtualThreadPerTaskExecutor()) {
ex.submit(() -> { /* 大量 IO */ });
}
// 模式 switch + 记录 + 密封:在 21 为 终态(对 前序 版 的 预览 形态 的 定稿),默认 无需 --enable-preview
public class Pets {
sealed interface Pet permits Cat, Dog { }
record Cat(String n) implements Pet { }
record Dog(String n) implements Pet { }
static String label(Pet p) {
return switch (p) {
case Cat c -> "cat " + c.n();
case Dog d -> "dog " + d.n();
};
}
}
import java.util.*;
SequencedCollection<String> sc = new LinkedList<>();
sc.addLast("a");
sc.addFirst("b");
// sc.getFirst();
预览 21:String Templates 等 见 后文 各 LTS/版本 的 定稿 说明。极简 void main() 在 25 起 可 经 JEP 512 定稿 见 §26。
// void main() { } // 在 25 前多为 preview;见 JEP 445/512 轨迹
23. Java SE 22(2024)
- FFM API(正式)、未命名变量/模式、多文件源码启动、Stream Gatherers(预览)、G1 区域固定 等;移除
Thread::countStackFrames。
正式 22:Foreign Function & Memory API 终态(JEP 454,包 java.lang.foreign),Arena 分配 与 按 布局 的 VarHandle 读 写 int:
import java.lang.foreign.*;
import java.lang.invoke.VarHandle;
ValueLayout.OfInt L = ValueLayout.JAVA_INT;
VarHandle h = L.varHandle();
try (Arena arena = Arena.ofConfined()) {
MemorySegment seg = arena.allocate(4, 4);
h.set(seg, 0L, 22);
System.out.println((int) h.get(seg, 0L));
}
如 你 的 JDK 为 MemorySegment 提供 getInt/setInt 等 简写,可 替 之;以 本 版本 JavaDoc 为准。
未命名 变量 _ 等 其它 终态/预览 以当版 JEP 为准。Stream 的 gather 在 22 为预览;正式 的 Stream::gather 见 §25(Java 24)。
24. Java SE 23(2024)
- 原语类型模式(预览)、类文件 API(预览二轮)、Markdown 文档注释、ZGC 默认分代、模块 import(预览) 等;String Templates 预览在 23 中撤回 以继续设计。
正式 23:Markdown 文档注释(JEP 467;javadoc 工具在生成 HTML 时按 Markdown 规则渲染常见标记):
/**
* # 标题示例
* - 列表 与 **加粗**(具体支持度以本 JDK 的 `javadoc` 帮助为准)
*/
public class ApiDoced23 {
/** 单句摘要 */
public void run() { }
}
其余如 ZGC 分代 默认 启用 多为 JVM 行为 与 启动 参数;类文件 API、模块 import、原语 模式 在 当版 的 定稿/预览 状态 见 发行 说明 与 各 JEP。
# 对上一文件生成 文档 时 启用 Markdown(以本机 javadoc 支持为准,例如 23+) # javadoc -d out ApiDoced23.java
25. Java SE 24(2025)
- Security Manager 永久禁用、类文件 API(正式)、Stream Gatherers(正式)、Scoped Values(预览多轮至定稿前)、JNI 使用收紧准备、删除 Win32 x86 端口、G1/ ZGC / Shenandoah 等 JVM 与 AOT 类加载 等(共数十 JEP,以 Release Notes 为准)。
正式 24:Stream::gather 与 内置 java.util.stream.Gatherers(JEP 485 终态;不 再 标 预览):
import java.util.List;
import java.util.stream.Gatherers;
import java.util.stream.Stream;
// 将元素按 固定 窗长 分块
List<List<Integer>> windows = Stream.of(1, 2, 3, 4, 5, 6, 7, 8)
.gather(Gatherers.windowFixed(3))
.toList();
System.out.println(windows);
另:类文件 API(JEP 484,包 java.lang.classfile)用于 读/写 class 文件 模型;Security Manager 永久 禁用 为 JVM/运行 行为,应用 侧 多 为 删 -Djava.security.manager 而 非 新 语法 示例。
26. Java SE 25(2025,LTS)
Java 25 是 LTS,在 语言、标准库、JVM、工具链 上有一批 JEP。下表按 定稿 / 仍为预览或孵化 区分;语法类以 JEP 511 / 512 / 513 为核心(在 23~24 多为 Preview,25 起为正式语言特性)。
26.1 本版 JEP 一览(与语法/用法的对应)
| JEP | 主题 | 在 25 中的状态(概要) |
|---|---|---|
| 511 | 模块 import:import module M; | 正式(语言) |
| 512 | 紧凑源文件 + 实例/简化 main + IO 类 | 正式(语言+库) |
| 513 | 灵活构造器体(super/this 前可写“前言”语句) | 正式(语言) |
| 506 | Scoped Values | 正式(java.util.concurrent 等) |
| 510 | 密钥派生(KDF)API | 正式 |
| 470 | PEM 编解码(密码对象) | 预览 |
| 502 | Stable Values | 预览 |
| 505 | Structured Concurrency | 第 5 预览 |
| 507 | 模式中的原始类型(instanceof / switch 等) | 第 3 预览 |
| 503 | 移除 32 位 x86 端口 | 平台(JDK 包不再提供该目标) |
| 519 | Compact Object Headers | JVM 默认能力(依构建而定) |
| 521 | 分代 Shenandoah | JVM |
| 508 | Vector API | 孵化(持续) |
| 514 / 515 | AOT 命令行与剖析 | 工具/JVM |
| 509 / 518 / 520 | JFR 能力扩展 | 监控 |
精确定义、边界条件与
javac/java开关以 JDK 25 Release Notes 与各 JEP 为准。
26.2 新语法一:import module(JEP 511,正式)
作用: 用一条声明按需导入某模块所 export 的包 里,对当前模块可见的 public 顶层 类型,相当于批量「按包 * import」,并能把 传递可读模块 里再 export 出来、并被你读到的包一并纳入作用域,从而减少 import 列表。
形式:
import module java.base; import module java.sql; // import module com.example.mylib; // 你方模块需在 module-info 中 requires 对应模块
示例 A:在普通类中省略大量 import(类路径 / 无 module-info 也可使用 JDK 具名模块)
import module java.base;
// 本文件在「未命名模块」、类路径上时,仍可使用对 JDK 的 import module
class PrintArgs {
public static void main(String[] args) {
var list = new java.util.ArrayList<String>();
for (var a : args) {
list.add(a);
}
System.out.println(String.join(", ", list));
}
}
javac --release 25 PrintArgs.java java PrintArgs a b c
示例 B:与 Swing 等同时用时需消歧(List 等业务常见名与 AWT 冲突)
import module java.desktop; import module java.base; import java.awt.Label; // 明确要 AWT 的 Label import java.util.List; // 明确要 java.util 的 List // ... 在方法中使用 Label、List
注意:
- 目标写的是 模块名(如
java.base),不能用import module去导入「无模块名」的 类路径/未命名模块 中的包;这与module-info里「依赖只能写具名模块」的模型一致。 - 若多模块里出现 简单名冲突(例如
List在 AWT 与java.util中),需再用 单类型 import 或 按包*消歧;Oracle 文档建议对Label、List等显式import java.awt.Label等(参见 Oracle 文档 Module Import Declarations)。 - 紧凑源文件(见 26.3)中,等价于已自动
import module java.base(可再写import module java.se等以扩大 API 面;java.se可能需--add-modules java.se)。
26.3 新语法二:紧凑源文件与main入口(JEP 512,正式)
目标: 小脚本/教学场景减少「public class + public static void main」的仪式,且不造一套独立方言;程序仍是「方法 → 类 → 包 → 模块」结构,只是由编译器隐式声明顶层类。
(1)普通类里:实例或简化的可启动 main
- 若存在带
String[](或String...) 的main,启动器优先选它并 static 调用(与传统一致)。 - 否则可选 无参
void main()等「可启动main」;若为 实例方法,JVM 会先用无参、非 private 构造器创建对象再调用实例main(无合适构造器则报错)。
(2)紧凑源文件(无包裹 class)
- 源文件中只有
import+ 顶层的field/method(等同类体成员),没有class关键字。 - 编译器隐式生成一个 final、无名包、仅默认无参构造、仅继承
Object的类;必须含至少一个可启动main,否则编译错误。 - 隐式类名由实现生成,源码中不要依赖该名字;也不能在源码里
new这个隐式类(教学向取舍)。
(3)java.lang.IO(JDK 25 起)
为入门场景提供行式 I/O,不再在紧凑源里隐式 static import IO.*,应写 IO.println(...) 或自行 import static(JEP 512 说明相对 24 的调整)。
示例(紧凑源文件,可直接 java Hello.java 运行):
import module java.base;
void main() {
IO.println("Hello, Java 25");
}
示例(具名类 + 无参实例入口):
class Hello {
void main() {
IO.println("Hi");
}
}
示例:启动器会优先选带 String[] 的 static main;下面会走传统入口,不会走无参 void main():
import module java.base;
class Launcher {
public static void main(String[] args) {
IO.println("args=" + java.util.List.of(args));
}
void main() {
IO.println("只有删除上面的 static main 时才会用实例 main");
}
}
示例:紧凑源里多个成员 + 子程序(仍须有一个可启动的 main)
将文件存为 Hello.java 后与 26.2 示例 A 一样使用 JDK 25+ 的源码启动或先 javac 再 java。
import module java.base;
String greet(String name) {
return "Hello, " + name;
}
void main() {
IO.println(greet("Java"));
}
java Hello.java # 或:javac --release 25 Hello.java && java Hello # 具体可运行类名以 javac 输出为准
与 26.2 配合: 在具名源文件顶行使用 import module java.base; 后,多数 java.util、java.io 等可不再逐类 import。
26.4 新语法三:灵活构造器体(JEP 513,正式)
原规则: 构造器体要么以 this(...)/super(...) 开头,要么编译器在开头插 super()。
新规则: 允许在显式的 this(...) / super(...) 之前写一段前言(prologue);在后的语句为后记(epilogue)。
前言处于 「早期构造期」 语义中:禁止用 this(含隐式) 访问未构造完成的实例、禁止随意调实例方法;允许对本类、且声明处没有内联初始化的 field 做简单赋值,以及不依赖 this 的纯计算,以便在调用父类构造前完成校验/准备。目的包括:在父类构造尚未把 this 暴露给子类前,把子类字段先置于一致状态、避免从父类构造回调看到「半初始化」子类状态。
示例 1:前言里做纯计算,再调用 super
class Base {
Base(int v) { }
}
class Sub extends Base {
private final int v;
Sub(int raw) {
int x = Math.max(0, raw);
super(x);
this.v = x;
}
}
示例 2:把校验从「挤在 super(…) 实参里」拆到前言(语义等价时更易读)
(旧写法常写作 super(Objects.requireNonNull(s, "msg").length()) 一类。)
import java.util.Objects;
class Base2 {
Base2(int len) { }
}
class Sub2 extends Base2 {
Sub2(String s) {
String t = Objects.requireNonNull(s, "s");
super(t.length());
}
}
注意:「早期构造期」禁止用
this调实例方法、读实例字段等;允许的语句集合、以及record紧凑构造等,以 Java 25 的 JLS 为准。
26.5 标准库定稿:Scoped Values(JEP 506)与 KDF(JEP 510)
Scoped Values — 在子调用栈上绑定只读上下文,子线程可继承(由 API 与 StructuredTaskScope 等配合),与 ThreadLocal 相比更偏向「多线程+结构化任务」里的明确边界。
示例(同一进程、单线程子调用链,演示 where / get)
import java.util.concurrent.ScopedValue;
public class ScopedDemo {
private static final ScopedValue<String> USER = ScopedValue.newInstance();
public static void main(String[] args) {
ScopedValue.where(USER, "alice").run(() -> {
System.out.println(USER.get());
m();
});
}
static void m() {
System.out.println("in m: " + USER.get());
}
}
KDF(JEP 510) — javax.crypto.KDF 与 javax.crypto.spec.HKDFParameterSpec 等,用标准算法名(如 HKDF-SHA256) 从 IKM、salt、info 派生 SecretKey 或原始字节。
示例:同一主密钥不同 info 派生多把独立材料(需 JDK 25+)
import javax.crypto.KDF;
import javax.crypto.SecretKey;
import javax.crypto.spec.HKDFParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Base64;
public class KdfDemo {
public static void main(String[] args) throws Exception {
byte[] ikm = new byte[32];
new SecureRandom().nextBytes(ikm);
byte[] salt = new byte[16];
new SecureRandom().nextBytes(salt);
KDF hkdf = KDF.getInstance("HKDF-SHA256");
byte[] encInfo = "app|v1|enc".getBytes(StandardCharsets.UTF_8);
AlgorithmParameterSpec encSpec = HKDFParameterSpec.ofExtract()
.addIKM(ikm)
.addSalt(salt)
.thenExpand(encInfo, 32);
SecretKey aes = hkdf.deriveKey("AES", encSpec);
byte[] macInfo = "app|v1|mac".getBytes(StandardCharsets.UTF_8);
AlgorithmParameterSpec macSpec = HKDFParameterSpec.ofExtract()
.addIKM(ikm)
.addSalt(salt)
.thenExpand(macInfo, 32);
byte[] macKey = hkdf.deriveData(macSpec);
System.out.println("AES: " + Base64.getEncoder().encodeToString(aes.getEncoded()));
System.out.println("MAC: " + Base64.getEncoder().encodeToString(macKey));
}
}
javac --release 25 KdfDemo.java java KdfDemo
若
HKDFParameterSpec的链式 API 与当前 JDK 小版本有出入,以 本机javax.crypto.spec.HKDFParameterSpec的 JavaDoc 为准。HKDF 假设 IKM 已有足够熵;用户口令 请用 PBKDF2 / Argon2 等专用口令 KDF,勿直接当 HKDF 的 IKM。
26.6 仍为预览的语言/ API(一般需用--enable-preview编译与运行;以发行说明为准)
以下示例在 JDK 25 下通常使用:
javac --release 25 --enable-preview YourFile.java java --enable-preview YourFile # 或源码直跑:java --enable-preview YourFile.java
1)JEP 502:Stable Values(java.lang.StableValue,预览 API) — 惰性、至多初始化一次、之后只读,适合懒加载单例等。
// javac --release 25 --enable-preview StablePreview.java
// java --enable-preview StablePreview
import java.lang.StableValue;
import java.util.logging.Logger;
public class StablePreview {
private static final StableValue<Logger> LOG = StableValue.of();
private static Logger logger() {
return LOG.orElseSet(() -> Logger.getLogger(StablePreview.class.getName()));
}
public static void main(String[] args) {
logger().info("ok");
}
}
2)JEP 507:原始类型与模式匹配(第 3 预览,语言预览) — 在 switch 等处使用 case int i、case int i when … 等,把原先写在 default 里再读一遍选择器的逻辑收紧到 case 上。
// 保存为 MapStatus.java
// 编译/运行需:javac --release 25 --enable-preview MapStatus.java
// java --enable-preview MapStatus
public class MapStatus {
public static void main(String[] args) {
System.out.println(mapStatus(99));
}
static String mapStatus(int code) {
return switch (code) {
case 0 -> "ok";
case 1 -> "warn";
case 2 -> "err";
case int i -> "other: " + i; // 绑定“其余 int 值”
};
}
}
3)JEP 505:结构化并发 — 使用 java.util.concurrent.StructuredTaskScope 等,在子任务失败时整体失败/关闭子任务,避免“孤儿”线程。以下演示 ShutdownOnFailure 与 fork / join / get(若编译器报预览特性,则对 javac / java 同样加上 --enable-preview)。
// StructConcDemo.java
import java.util.concurrent.StructuredTaskScope;
public class StructConcDemo {
public static void main(String[] args) throws Exception {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
var a = scope.fork(() -> "x");
var b = scope.fork(() -> 1);
scope.join();
scope.throwIfFailed();
System.out.println(a.get() + b.get());
}
}
}
javac --release 25 StructConcDemo.java java StructConcDemo
4)JEP 470:PEM 编解码、5)JEP 505 的其它形态 等,包名/工厂方法以 JEP 与 25u JavaDoc 为准,此处不展开贴长示例。
生产环境是否启用需团队统一;预览在定稿时可能有小改。
26.7 JVM、平台与观测(与「写语法」关系较弱但常一起升级)
- 移除 32 位 x86 端口(JEP 503):不再提供该目标的构建;老机器需换 64 位或留在旧 JDK。
- Compact Object Headers(JEP 519)、分代 Shenandoah(JEP 521):堆内对象头与低延迟 GC 的演进,影响内存与 STW/吞吐,不直接改 Java 语法。
- AOT 命令行/剖析(JEP 514/515)、JFR 扩展(JEP 509/518/520)、Vector API 继续孵化(JEP 508):偏向运维、性能与原生向量计算。
小结: 若只记 Java 25 「新语法三件套」,即 import module、紧凑源/实例与简化 main、灵活构造器体;其余多为 库定稿、预览特性与 JVM/工具。与 Java 24 的差异请对照 你当前 javac/java 的 --help extra 与发行说明。
27. Java SE 26(2026-03)
- 含 HTTP/3 客户端(JEP 517)、移除 Applet API(JEP 504)等。细节以 OpenJDK 26 与发行说明为准。
正式 26:在 java.net.http.HttpClient 上显式 首选 HTTP/3(若 对 端/网络 不 支持 则 自动 协商 降 为 HTTP/2 或 1.1,见 JEP 517):
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.time.Duration;
// 需 Java 26+ 且 本 版本 的 HttpClient 暴露 Version.HTTP_3
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_3)
.connectTimeout(Duration.ofSeconds(10))
.build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://openjdk.org/"))
.GET()
.build();
// HttpResponse<String> res = client.send(request, HttpResponse.BodyHandlers.ofString());
// System.out.println(res.version());
另:已标记 移除的 Applet API 的 使用 在 新 代 JDK 中 应 删除 或 迁移;无 需 在 新 项目 中 给 可运行 的 Applet 示例。
Java SE 27(计划,未 GA)
- 不附「新终态」示例:待正式发行后,以 JDK、JEP 与 JLS 更新为准在本文中增补。
28. 工具链与release编译
查看运行时:
java -version
按目标版本编译(推荐 release,避免误用高版本 API):
javac --release 17 -d out src/com/example/App.java
Maven 示例:
<properties> <maven.compiler.release>17</maven.compiler.release> </properties>
29. 速查:能力 → 约最低版本
| 能力 | 约从 |
|---|---|
| 泛型/注解/enum/for-each | 5 |
| try-with-resources / NIO.2 路径 | 7 |
| Lambda/Stream/java.time | 8 |
| 模块/工厂不可变集合 | 9 |
var | 10 |
标准 HttpClient / 字符串 strip 等 | 11 |
文本块 / record / 密封 | 15~17 |
| 虚拟线程 | 21(正式) |
| FFM(Panama)定稿 | 22 |
import module、紧凑源/简化 main、灵活构造器体 | 25(正式) |
更细的 JEP 编号、预览/定稿 以对应版本的 OpenJDK Release Notes 为准;若写生产代码,团队应固定 LTS 与 --enable-preview 策略。
30. 参考
- 版本年表与特性摘要:Wikipedia: Java version history(与人名、日期交叉核对)
- 正式规范以 JLS、JVMS、各版 JDK Release Notes 为准。
到此这篇关于Java全版本特性与用法示例(含总览+分版本要点)的文章就介绍到这了,更多相关Java全版本特性与用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Jrebel License Server 激活 IDEA-Jrebel-在线-
这篇文章主要介绍了Jrebel License Server 激活 IDEA-Jrebel-在线-离线-均适用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-12-12
SpringBoot使用责任链模式优化业务逻辑中的if-else代码
在开发过程中,我们经常会遇到需要根据不同的条件执行不同的逻辑的情况,我们可以考虑使用责任链模式来优化代码结构,使得代码更加清晰、可扩展和易于维护2023-06-06
SpringBoot解决跨域导致sessionId不一致的实现方式
本文描述了使用SpringBoot和谷歌kaptcha做验证码登录校验时遇到的跨域问题,并通过设置SameSite属性、使用https和redis等方式解决了问题2026-04-04


最新评论