前言
ScopedValue
在JDK21
引入的预览属性,在后续的JDK版本中一直预览,然而在JDK24
和稳定版JDK25
中,有些许调整
JDK24调整
JDK24
去掉了runWhere
和callWhere
方法,直接使用where
方法了
csharp
public class ScopedValueDemo {
private static ScopedValue<String> stringScopedValue = ScopedValue.newInstance();
public static void main(String[] args) {
ScopedValue.where(stringScopedValue, say()).run(() -> {
System.out.println(stringScopedValue.get());
});
}
public static String say() {
System.out.println("============say()方法");
return "aaa";
}
}
输出结果如下

JDK25调整,
ScopedValue
在JDK25
正式转正了,也就是不再是预览属性了,可以正式使用了,只是有个方法做了以下调整,ScopedValue.orElse()方法不再接受null作为参数 JDK24
源码
JDK25
源码

java
import java.lang.ScopedValue;
public class ScopedValueOrElseExample {
private static final ScopedValue<String> USER_ID = ScopedValue.newInstance();
public static void main(String[] args) {
// 场景1:未绑定值时,使用 orElse() 提供默认值
String userId1 = USER_ID.orElse(null);
System.out.println("未绑定值时:" + userId1);
}
}
输出结果为

typescript
import java.lang.ScopedValue;
public class ScopedValueOrElseExample {
private static final ScopedValue<String> USER_ID = ScopedValue.newInstance();
public static void main(String[] args) {
// 场景1:未绑定值时,使用 orElse() 提供默认值
String userId1 = USER_ID.orElse("aaaa");
System.out.println("未绑定值时:" + userId1); // 输出:aaaa
// 场景2:绑定值后,orElse() 会返回绑定值
ScopedValue.where(USER_ID, "hello world").run(() -> {
String userId2 = USER_ID.orElse("default_user");
System.out.println("绑定值后:" + userId2); // 输出:hello world
});
// 场景3:在子方法中使用 orElse()
printUserId();
}
private static void printUserId() {
// 子方法中未绑定值,使用默认值
String userId = USER_ID.orElse("unknown_user");
System.out.println("子方法中:" + userId); // 输出:unknown_user
}
}
输出结果为

总结
在JDK25中,JEP 506
终于转正,也就是说,ScopedValue
在JDK25
正式转正了,也就是不再是预览属性了,可以放心大胆的使用该语法糖了,可以用来代替ThreadLocal