如何初始化ThreadLocal <list <object>&gt;

时间:2017-02-17 08:10:59

标签: java nullpointerexception thread-local

以下是我的代码,其中我声明了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)获得价值。

3 个答案:

答案 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,特别是如果您没有使用它的经验。