Java历代LTS版本新特性详解(代码增强版)

前言

Java 在2017年调整发布策略:每6个月发布一个非LTS预览版本,每3年发布一个LTS长期支持版本。

非LTS版本:9、10、12、13、14、15、16、18、19、20、22、23、24、26、27,本文仅罗列,不讲解特性。

LTS版本(生产环境推荐):Java8、Java11、Java17、Java21、Java25

本文只讲解LTS版本,每个特性附带完整可运行代码 + 详细解读 + 运行结果,方便直接复制测试、学习、面试复习。

Java版本总览

✅ LTS:Java8、Java11、Java17、Java21、Java25(重点讲解)

❌ 非LTS:Java9、10、12、13、14、15、16、18、19、20、22、23、24、26、27

迭代主线:Java8奠定函数式编程 → Java11补齐基础API → Java17增强封装与代码规范 → Java21革新并发模型(虚拟线程) → Java25面向高性能计算、AI本地计算、原生跨语言调用


Java 8(2014 LTS)现代Java的基石

Java8是Java史上最重要版本,引入函数式编程,是国内绝大多数存量项目基线。

1. Lambda表达式

解读:Lambda本质是简化函数式接口(只有一个抽象方法的接口)的匿名内部类写法,可以把代码块当作参数传递。

java 复制代码
import java.lang.Runnable;
import java.util.Comparator;
import java.util.List;
import java.util.Arrays;

public class LambdaDemo {
    public static void main(String[] args) {
        // 1. 传统匿名内部类写法
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("传统匿名内部类线程");
            }
        }).start();

        // 2. Lambda写法:无参
        new Thread(() -> System.out.println("Lambda线程")).start();

        // 3. 带参数Lambda,集合排序
        List<String> names = Arrays.asList("Zhang", "Li", "Wang");
        // 比较器
        names.sort((s1, s2) -> s1.length() - s2.length());
        System.out.println(names);
    }
}

输出:

复制代码
传统匿名内部类线程
Lambda线程
[Li, Wang, Zhang]

2. Stream流式API

解读:声明式集合处理,分为中间操作(lazy,不会立即执行)、终端操作(触发执行)。中间操作:filter、map、sorted;终端操作:collect、forEach、count。

java 复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamDemo {
    public static void main(String[] args) {
        List<Integer> nums = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

        List<Integer> result = nums.stream()
                .filter(n -> n % 2 == 0)        // 过滤偶数
                .map(n -> n * n)                // 每个数字平方
                .sorted(Integer::compareTo)     // 排序
                .collect(Collectors.toList());  // 收集成List

        System.out.println(result); // [4, 16, 36, 64, 100]

        // 聚合操作:求和、计数
        long count = nums.stream().filter(n -> n >5).count();
        System.out.println("大于5的数字数量:" + count);

        // 并行流,利用多核CPU
        nums.parallelStream().forEach(System.out::println);
    }
}

3. java.time 全新日期时间API

解读 :旧Date、Calendar可变,线程不安全;java.time包下所有对象都是不可变类,线程安全。

java 复制代码
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.Duration;
import java.time.Period;

public class TimeDemo {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        LocalDate birthday = LocalDate.of(1995, Month.AUGUST, 21);
        LocalTime nowTime = LocalTime.now();
        LocalDateTime dateTime = LocalDateTime.now();

        System.out.println("今天日期:" + today);
        System.out.println("生日:" + birthday);
        System.out.println("当前时间:" + nowTime);
        System.out.println("日期时间:" + dateTime);

        // 日期加减
        LocalDate next3Day = today.plusDays(3);
        LocalDate lastMonth = today.minusMonths(1);
        System.out.println("3天后:" + next3Day);
        System.out.println("上月今天:" + lastMonth);

        // 计算两个日期相差多少年、月、日
        Period period = Period.between(birthday, today);
        System.out.printf("年龄:%d年%d月%d日%n", period.getYears(), period.getMonths(), period.getDays());
    }
}

4. Optional 空值容器

解读 :用于包装可能为null的对象,强制开发者处理空值场景,减少大量if(obj != null)嵌套,降低NPE风险。

java 复制代码
import java.util.Optional;

public class OptionalDemo {
    public static void main(String[] args) {
        String str1 = null;
        String str2 = "Hello Java8";

        // ofNullable:允许传入null;of()传入null会直接抛NPE
        Optional<String> optNull = Optional.ofNullable(str1);
        Optional<String> optVal = Optional.ofNullable(str2);

        // orElse:为空返回默认值
        String val1 = optNull.orElse("空字符串默认值");
        System.out.println(val1);

        // ifPresent:不为空才执行逻辑
        optVal.ifPresent(s -> System.out.println("不为空:" + s));

        // map转换,空的时候不会执行映射
        Optional<Integer> lenOpt = optVal.map(String::length);
        lenOpt.ifPresent(len -> System.out.println("字符串长度:" + len));

        // 为空抛出异常
        // optNull.orElseThrow(() -> new RuntimeException("数据不存在"));
    }
}

5. CompletableFuture 异步编程

解读:旧Future只能阻塞等待结果;CompletableFuture支持链式回调、多任务组合、异常回调,非阻塞异步。

java 复制代码
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

public class CompletableFutureDemo {
    public static void main(String[] args) throws Exception {
        // 异步执行任务
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "任务执行结果";
        }).thenApply(res -> {
            // 任务成功后转换结果
            return res + " -> 追加处理";
        }).exceptionally(ex -> {
            // 捕获异常
            return "任务异常:" + ex.getMessage();
        });

        String result = future.get(); // 阻塞获取结果
        System.out.println(result);
    }
}

6. 接口默认方法

解读:接口可以带默认实现,接口新增方法时,不会破坏已有实现类的兼容性。

java 复制代码
interface Animal {
    default void say() {
        System.out.println("动物发出声音");
    }
}

class Dog implements Animal {
}

public class InterfaceDefaultDemo {
    public static void main(String[] args) {
        new Dog().say();
    }
}

Java11(2018 LTS)轻量化生产首选

1. 内置HttpClient(正式版)

解读:JDK原生HTTP客户端,支持HTTP/2、WebSocket,同步+异步,不需要引入OkHttp、RestTemplate第三方依赖。

java 复制代码
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;

public class HttpClientDemo {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("[https://httpbin.org/get](https://httpbin.org/get)"))
                .GET()
                .build();

        // 同步请求
        HttpResponse<String> resp = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println("状态码:" + resp.statusCode());
        System.out.println("响应体:" + resp.body());

        // 异步请求
        CompletableFuture<HttpResponse<String>> futureResp = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
        futureResp.thenAccept(r -> System.out.println("异步响应:" + r.body())).join();
    }
}

2. String新增工具方法

java 复制代码
public class StringDemoJava11 {
    public static void main(String[] args) {
        String blank = "   \t ";
        String text = "  Java11  ";

        System.out.println(blank.isBlank());       // true,判断空白字符(空格、制表符)
        System.out.println(text.strip());          // Java11,去除首尾空白(支持全角空格,优于trim)
        System.out.println(text.stripLeading());   // "Java11  ",只去开头空白
        System.out.println(text.stripTrailing());  // "  Java11",只去末尾空白
        System.out.println("Hi".repeat(3));        // HiHiHi,重复字符串

        // lines() 按行拆分成流
        String multiLine = "A\nB\nC";
        multiLine.lines().forEach(System.out::println);
    }
}

3. Files.readString / Files.writeString

解读:一行代码读写文本文件,不用手动关闭流,简化IO操作。

java 复制代码
import java.nio.file.Files;
import java.nio.file.Paths;

public class FileDemoJava11 {
    public static void main(String[] args) throws Exception {
        String content = "Java11 文件读写测试";
        // 写入文件
        Files.writeString(Paths.get("demo.txt"), content);
        // 读取文件
        String read = Files.readString(Paths.get("demo.txt"));
        System.out.println(read);
    }
}

4. Lambda参数支持var

java 复制代码
import java.util.List;
import java.util.Arrays;

public class LambdaVarDemo {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("a", "b", "c");
        list.forEach((var s) -> System.out.println(s));
    }
}

Java17(2021 LTS)企业生态基线版本

SpringBoot3、Spring6最低基线版本,主打API安全、强封装。

1. 密封类 Sealed Classes

解读 :sealed + permits 显式限定哪些类可以继承当前类,防止子类无限制扩展,适合开发框架、SDK,控制对外API。

java 复制代码
// 密封类,只允许Circle、Rectangle继承
public sealed class Shape permits Circle, Rectangle {
}

// final 子类,不能再被继承
final class Circle extends Shape {
    private double radius;
    public Circle(double radius) { this.radius = radius; }
    public double getArea() { return Math.PI * radius * radius; }
}

final class Rectangle extends Shape {
    private double w,h;
    public Rectangle(double w, double h) {
        this.w = w;
        this.h = h;
    }
    public double getArea() { return w * h; }
}

public class SealedDemo {
    public static void main(String[] args) {
        Shape c = new Circle(2);
        Shape r = new Rectangle(3,4);
        System.out.println("Circle Area:" + ((Circle)c).getArea());
        System.out.println("Rect Area:" + ((Rectangle)r).getArea());
    }
}

补充说明:Records、instanceof模式匹配是Java16转正(非LTS版本),Java17 LTS中可以直接使用,开发很常用:

java 复制代码
// Record:不可变数据载体,自动生成构造器、getter、equals、hashCode、toString
record User(Long id, String name) {}

public class RecordDemo {
    public static void main(String[] args) {
        User u = new User(1L, "zhangsan");
        System.out.println(u.id());
        System.out.println(u.name());
        System.out.println(u);

        // instanceof 模式匹配
        Object obj = "test string";
        if(obj instanceof String s) {
            System.out.println(s.length());
        }
    }
}

2. 底层特性说明

  1. JDK内部API强封装:禁止反射访问sun.misc等内部API,提升安全;
  2. SecurityManager被废弃,不再推荐使用;
  3. ZGC持续优化,GC停顿进一步降低。

Java21(2023 LTS)并发模型革新

1. 虚拟线程 Virtual Threads(正式)

解读:JVM管理轻量级线程,不绑定操作系统内核线程。创建成本极低,可以创建百万级虚拟线程;代码写法和传统同步代码完全一致,不需要回调,非常适合IO密集型服务(HTTP调用、数据库查询)。

java 复制代码
import java.util.concurrent.Executors;

public class VirtualThreadDemo {
    public static void main(String[] args) {
        // 创建虚拟线程执行器,每个任务自动创建一个虚拟线程
        try(var executor = Executors.newVirtualThreadPerTaskExecutor()){
            // 提交10000个任务
            for(int i = 0; i < 10000; i++){
                int taskId = i;
                executor.submit(() -> {
                    // 模拟IO等待
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println("虚拟线程任务:" + taskId);
                });
            }
        }
        // try-with-resources会自动等待所有虚拟线程执行完毕,关闭executor
        System.out.println("所有任务执行完成");
    }
}

2. Switch模式匹配(正式)

解读 :支持类型匹配,替代大量if(obj instanceof X)判断,代码更简洁。支持Record解构。

java 复制代码
record Point(int x, int y){}

public class SwitchPatternDemo {
    public static String match(Object obj) {
        return switch(obj) {
            case Integer i -> "整数:" + i;
            case String s -> "字符串:" + s;
            case Point(int x, int y) -> "坐标点 x=" + x + ",y=" + y;
            default -> "未知类型";
        };
    }

    public static void main(String[] args) {
        System.out.println(match(99));
        System.out.println(match("Java21"));
        System.out.println(match(new Point(10,20)));
    }
}

3. 结构化并发(预览)

Java21结构化并发为预览特性,Java25正式转正,用于把一组任务当作一个单元管理,任务失败自动取消子任务,避免线程泄漏。


Java25(2025 LTS)高性能 & AI原生版本

1. Vector API(正式,SIMD向量计算)

解读:调用CPU的SIMD指令,单指令多数据,批量数值运算,适合向量计算、AI向量推理、矩阵运算、信号处理。

java 复制代码
import jdk.incubator.vector.FloatVector;
import jdk.incubator.vector.VectorSpecies;
import java.util.Arrays;

public class VectorApiDemo {
    public static void main(String[] args) {
        // 获取当前CPU支持的最优向量宽度
        VectorSpecies<Float> species = FloatVector.SPECIES_PREFERRED;
        float[] src = {1,2,3,4,5,6,7,8};
        float[] dst = new float[8];

        // 从数组加载向量
        FloatVector vector = FloatVector.fromArray(species, src, 0);
        // 向量批量加法:每个元素+2
        FloatVector resultVec = vector.add(2.0f);
        // 结果写回数组
        resultVec.intoArray(dst, 0);

        System.out.println(Arrays.toString(dst));
        // [3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
    }
}

2. 外部函数与内存API(FFM API,正式)

解读:替代老旧JNI,安全高效调用C/C++原生库,直接操作堆外内存,不需要写C++胶水代码。适合调用AI本地模型库、底层系统库。

示例:调用C标准库strlen函数(需要引入对应的外部库路径)

java 复制代码
import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.Linker;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;

public class FFMDemo {
    public static void main(String[] args) throws Throwable {
        try(Arena arena = Arena.ofConfined()) {
            // 分配堆外内存,写入字符串
            MemorySegment str = arena.allocateFrom("Hello Java25 FFM");
            // 获取C库strlen方法句柄
            Linker linker = Linker.nativeLinker();
            MethodHandle strlen = linker.downcallHandle(
                    linker.defaultLookup().find("strlen").orElseThrow(),
                    FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS)
            );
            long len = (long) strlen.invoke(str);
            System.out.println("字符串长度:" + len);
        }
    }
}

3. 结构化并发 & Scoped Values(正式)

解读:Scoped Values替代ThreadLocal,配合虚拟线程,安全传递链路上下文(traceId、用户信息),自动释放,无内存泄漏。结构化并发把一组子任务作为一个整体管理,任一任务异常,自动取消全部子任务。

java 复制代码
import java.util.concurrent.Executors;
import java.util.concurrent.StructuredTaskScope;
import java.util.concurrent.ScopedValue;

public class StructuredConcurrencyDemo {
    // 定义作用域变量
    private static final ScopedValue<String> TRACE_ID = ScopedValue.newInstance();

    public static void main(String[] args) throws Exception {
        ScopedValue.where(TRACE_ID, "trace-12345").run(() -> {
            try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
                var task1 = scope.fork(() -> {
                    System.out.println("任务1 traceId: " + TRACE_ID.get());
                    return "任务1结果";
                });
                var task2 = scope.fork(() -> {
                    System.out.println("任务2 traceId: " + TRACE_ID.get());
                    return "任务2结果";
                });
                scope.join();
                scope.throwIfFailed();
                System.out.println(task1.get() + "," + task2.get());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }
}

4. 增强模式匹配

Java25进一步增强模式匹配:支持原始类型模式、嵌套记录模式,解构复杂对象,简化分支判断。

java 复制代码
record Order(Long id, User user){}
record User(String name){}

public class NestedPatternDemo {
    public static void main(String[] args) {
        Object obj = new Order(1001L, new User("test"));
        if(obj instanceof Order(Long id, User(String name))) {
            System.out.println("订单ID:" + id + ",用户名:" + name);
        }
    }
}

LTS版本选型汇总表

LTS版本 核心定位 适用场景
Java8 函数式编程奠基,稳定 存量老项目、传统业务系统
Java11 API补齐,轻量化 中小型项目,Java8低成本升级
Java17 生态标准、强封装 SpringBoot3微服务、企业通用项目
Java21 云原生、高并发IO 网关、接口服务、大量IO等待场景
Java25 AI向量计算、跨语言调用 AI本地推理、高性能计算、底层中间件新项目

结尾

Java的LTS版本迭代方向:不断简化代码语法、降低并发开发成本、提升性能,同时扩展Java边界,支持SIMD向量计算、原生调用C库。生产环境优先选择LTS版本,非LTS版本仅用来提前体验新特性,不建议上生产。

相关推荐
李少兄1 小时前
深度剖析 Hutool ObjectUtil
java·开发语言
魏码不凡1 小时前
Go 编译报错:undefined: webp.Encode 问题排查与解决
开发语言·后端·golang
27669582921 小时前
youdao/有道翻译APP 算法协议分析
开发语言·前端·python·sign·youdao·有道翻译app算法·有道app协议请求
励志不掉头发的内向程序员1 小时前
【从零写一个CAD 04】中键拖动平移:抓住一个点,让它一直待在鼠标底下
开发语言·c++·qt·学习·系统架构·计算机外设
tachibana23 小时前
与其他语言相比,使用 Go 有什么好处?
开发语言·后端·golang·go
阿俊-全栈开发7 小时前
LikeShop 单商户SaaS商城分销模块二开:佣金计算与结算逻辑实现
java·开发语言·微服务·likeshop·likeshop开源商城·likeshop多商户
夏天拐跑了西瓜9 小时前
一文入门LangChain:从框架认知到构建你的第一个AI Agent
python·langchain·conda·agent
魔猴疯猿10 小时前
从0到1用Python开发第一个智能体
人工智能·python·深度学习·神经网络·机器学习
wuminyu10 小时前
C++协程实现接收端的零拷贝Buffer管理原理剖析
java·linux·c语言·jvm·c++