A ScopedValue must be accessible within the functional task where it is bound. Creating a new instance directly inside a
ScopedValue.where() call makes the key unreachable, as there is no variable name to reference when calling .get().
The primary purpose of a ScopedValue is to provide a way to share data without passing it as method arguments. To retrieve the value
using .get(), you must have access to the ScopedValue instance (the key).
If a ScopedValue is instantiated anonymously within the .where() method, it is "lost" immediately after the binding is
created. The code inside the Runnable or Callable has no way to reference that specific instance to retrieve the associated
value, rendering the scoped value useless.
Assign the ScopedValue instance to a stable reference — typically a static final field — before using it in a binding.
This allows different parts of the code to refer to the same key to set and retrieve values.
public class Renderer {
public void process() {
// Noncompliant: The ScopedValue instance is anonymous and unreachable inside the run method
ScopedValue.where(ScopedValue.newInstance(), "DARK").run(() -> {
render();
});
}
void render() {
// There is no way to call .get() here because the key is unknown
}
}
public class Renderer {
// Compliant: The ScopedValue is assigned to a constant that can be referenced elsewhere
private static final ScopedValue<String> THEME = ScopedValue.newInstance();
public void process() {
ScopedValue.where(THEME, "DARK").run(() -> {
render();
});
}
void render() {
System.out.println("Theme is: " + THEME.get());
}
}