Following is my code, in which I am declaring a ThreadLocal variable:
public static final ThreadLocal<List<Object>> ARGS = new ThreadLocal<>();
I'm using this variable in the below snippet:
private static void getParams(Token... tokens) {
if(ARGS == null) {
new LinkedList<>();
}
if(tokens.length > 2) {
for(Token token : Arrays.copyOfRange(tokens, 2, tokens.length)) {
ARGS.get().add(ArgHelper.resolveArg(token));
}
}
}
The below line:
ARGS.get().add(ArgHelper.resolveArg(token));
is giving me NullPointerException thou I'm getting value from ArgHelper.resolveArg(token).
Notice that:
if(ARGS == null) {
new LinkedList<>();
}
doesn't do anything. ARGS is created as a final non-null value, so this block will never be entered. Even if it did, calling new LinkedList<>(); all alone simply constructs a LinkedList instance that immediately falls out of scope and is garbage collected. Nothing can reference it.
To properly initialize a ThreadLocal look at the documentation, which provides an example showing how to set an initial-value (by overriding the aptly-named initialValue() method).
You can do something similar:
public static final ThreadLocal<List<Object>> ARGS = new ThreadLocal<List<Object>>() {
@Override protected List<Object> initialValue() {
return new LinkedList<>();
}
};
That said, some pointers:
ArrayList over LinkedList in almost all cases.ARGS private unless absolutely necessary. It's generally best to minimize the visibility of ThreadLocal instances, e.g. limiting it to the containing class, and exposing a nicer API to users of that class.List<Object> - you force all users to inspect and cast the contents of the list if it can hold any Object.Java 8
private static final ThreadLocal<List<Object>> list =
ThreadLocal.withInitial(ArrayList::new);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With