以下是我的代码,其中我声明了ThreadLocal
变量:
public static final ThreadLocal<List<Object>> ARGS = new ThreadLocal<>();
我在下面的代码段中使用了这个变量:
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));
}
}
}
以下行:
ARGS.get().add(ArgHelper.resolveArg(token));
正在给我NullPointerException
我从ArgHelper.resolveArg(token)
获得价值。
答案 0 :(得分:2)
请注意:
if(ARGS == null) {
new LinkedList<>();
}
没有做任何事情。 ARGS
创建为final
非空值,因此永远不会输入此块。即使它确实如此,单独调用new LinkedList<>();
只会构造一个立即超出范围并被垃圾收集的LinkedList
实例。没有什么可以参考它。
正确初始化ThreadLocal
查看documentation,其中提供了一个示例,说明如何设置初始值(通过覆盖恰当命名的initialValue()
方法)。
你可以做类似的事情:
public static final ThreadLocal<List<Object>> ARGS = new ThreadLocal<List<Object>>() {
@Override protected List<Object> initialValue() {
return new LinkedList<>();
}
};
那说了一些指示:
ArrayList
而不是LinkedList
。ARGS
private
。通常最好将ThreadLocal
个实例的可见性降至最低,例如将其限制为包含类,并向该类的用户公开更好的API。List<Object>
更有意义的类型 - 强制所有用户检查并转换列表的内容(如果它可以容纳任何Object
。答案 1 :(得分:1)
Java 8
private static final ThreadLocal<List<Object>> list =
ThreadLocal.withInitial(ArrayList::new);
答案 2 :(得分:0)
这不是您使用ThreadLocal
的方式。
您可能希望以下内容初始化空线程本地。而不是您的代码损坏。
if(ARGS.get() == null) {
ARGS.set(new LinkedList<>());
}
当然,我建议不要使用ThreadLocal
,特别是如果您没有使用它的经验。