Java25新特性:稳定值

JEP502:该特性为预览特性,并将在Java26的JEP526做第二次预览。初看介绍,"一个持有不可变数据的对象",不就是final对象吗?

原来,它添加了对延迟不可变性的原生支持。与final相比,它延迟初始化到首次使用时赋值,不需要在构造时立即赋值;并且可以依赖运行时条件,增加了代码灵活性。

java 复制代码
import java.lang.StableValue;
import java.util.logging.Logger;

public class OrderService {

    private final StableValue<Logger> logger = StableValue.of();

    Logger getLogger() {
        // 首次调用时初始化,后续直接返回,线程安全
        return logger.orElseSet(() -> Logger.getLogger(OrderService.class.getName()));
    }

    void submitOrder() {
        getLogger().info("正在下单...");
        // ...
        getLogger().info("下单完成!");
    }
}

稳定值被赋值后,引用不可更改,但对象内部状态仍然可变,赋值后JVM可像优化final字段一样进行常量折叠。


常量折叠是编译器在编译期间自动执行的一项优化操作。

java 复制代码
public class ConstantFoldingExample {
    public static void main(String[] args) {
        final int a = 5;
        final int b = 10;
        int c = a + b;
        System.out.println(c);
    }
}

a+b 是一个常量表达式,因为ab都是final修饰的常量,在编译时,编译器会将这个表达式的结果(即15)直接嵌入到生成的代码中,因此运行时不需要再次计算**a+b**。


再看一下手搓单例模式的区别。

以前的方式:双重检查锁定(volatile + synchronized)

java 复制代码
public class OldSingleton {
    private static volatile OldSingleton instance;

    // 私有构造
    private OldSingleton() {
        System.out.println("[" + Thread.currentThread().getName() + "] 初始化单例...");
    }

    // 双重检查锁定
    public static OldSingleton getInstance() {
        // 第一次检查(无锁)
        if (instance == null) {
            synchronized (OldSingleton.class) {
                // 第二次检查(加锁后)
                if (instance == null) {
                    instance = new OldSingleton();
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) {
        System.out.println("=== 单例测试 ===");

        // 多线程并发测试
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                OldSingleton s = OldSingleton.getInstance();
                System.out.println("获取实例: " + s.hashCode());
            }, "Thread-" + i).start();
        }
    }
}

执行结果:

Java 25的方式: (CAS原子操作)

java 复制代码
import java.util.function.Supplier;

public class NewSingleton {
    private static final StableValue<NewSingleton> INSTANCE = StableValue.of();

    private NewSingleton() {
        System.out.println("[" + Thread.currentThread().getName() + "] 初始化单例...");
    }

    public static NewSingleton getInstance() {
        return INSTANCE.orElseSet(NewSingleton::new);
    }

    // 使用Supplier接口
    public static class SupplierVersion {
        // 直接返回Supplier,调用方无需知道StableValue存在
        private static final Supplier<NewSingleton> INSTANCE =
                StableValue.supplier(NewSingleton::new);

        public static NewSingleton getInstance() {
            return INSTANCE.get();
        }
    }

    public static void main(String[] args) {
        System.out.println("=== Java 25 StableValue单例测试 ===");

        // 多线程并发测试
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                NewSingleton s = NewSingleton.getInstance();
                System.out.println("获取实例: " + s.hashCode());
            }, "Thread-" + i).start();
        }

        // 测试Supplier版本
        System.out.println("=== Supplier 版本测试 ===");
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                NewSingleton s = SupplierVersion.getInstance();
                System.out.println("Supplier获取: " + s.hashCode());
            }, "SupplierThread-" + i).start();
        }
    }
}

执行结果:

Java25的单例模式核心就一行:

java 复制代码
private static final StableValue<NewSingleton> INSTANCE = StableValue.of();

原来Java也在不断的向前追赶着,更高效,也更简洁。

相关推荐
鹿角片ljp22 分钟前
LeetCode 64:最小路径和复盘|二维 DP 与 ACM 模式完整写法
java·数据结构·算法
泡海椒2 小时前
PDF 表格样式优化:jquick-pdf 边框、圆角、背景色
java·开发语言·pdf
景熙55233 小时前
15.Java 8 Stream 流入门到实战
java·开发语言·数据结构
wno7043 小时前
Spring Security权限控制
java·python·spring
杨运交4 小时前
[071][验证码模块]基于Spring拦截器的验证码认证设计思想
java·后端·spring
Geek-Chow4 小时前
CountDownLatch in Java
java
SL_staff5 小时前
从RBAC到场景化授权:《无忧·企业文档》三级权限模型的技术实践解析
java·开源·产品
传奇开心果编程5 小时前
【springboot基础语法学与练】第 1 课:从零开始
java·spring boot·后端·学习
SL_staff5 小时前
财务系统慎用低代码?从数据模型闭环看合规落地的技术实践
java·低代码·全栈