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也在不断的向前追赶着,更高效,也更简洁。

相关推荐
EXI-小洲10 分钟前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
2601_961901701 小时前
SpringBoot使用Nacos进行application.yml配置管理
java·spring boot·spring
何以解忧,唯有..2 小时前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain
QQ_21696290962 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端
前端 贾公子3 小时前
第09章:上下文与记忆 (2)
java·服务器·前端
2601_962203514 小时前
Java进阶07集合(续)
java·开发语言
郑州光合科技余经理4 小时前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
roman_日积跬步-终至千里4 小时前
【数据治理(6)】DataOps 不是调度工具,而是让数据产品长期可信的运行机制
java·服务器·网络
落魄大学生之流水线上谋生计4 小时前
LangGraph 基本用法指南
java·windows·python·langchain
2601_962128415 小时前
SpringBoot篇(缓存层)
java·spring boot·缓存