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

相关推荐
我登哥MVP1 小时前
走进 Gang of Four 设计模式:解释器模式
java·设计模式·解释器模式
智码看视界1 小时前
Tomcat架构深度拆解:Connector和Container到底怎么配合的?
java·servlet·架构·tomcat·web服务器
浪客川1 小时前
idea 技巧 region 的使用
java·ide·intellij-idea
CHANG_THE_WORLD1 小时前
逐层拆解:C++ 虚函数从对象内存到手工调用的完整过程
java·开发语言·c++
我登哥MVP1 小时前
走进 Gang of Four 设计模式:过滤器模式
java·设计模式·过滤器模式
吃饱了得干活2 小时前
实时弹幕应该怎么搞?一篇带你从入门到生产级实战
java·后端
tianyuanwo2 小时前
深入掌握 java -jar 命令:从基础到 Jenkins Agent 实战
java·jenkins·jar
Full Stack Developme2 小时前
MyBatis-Plus(MP)AST 抽象语法树 设计原理
java·tomcat·mybatis
宠友信息2 小时前
消息撤回与已读状态如何在即时通讯源码中统一管理
java·spring boot·websocket·mysql·uni-app