0
public class SipResponseCollection {

    private final static Logger LOGGER=Logger.getLogger(SipResponseCollection.class);
    private volatile Map<String, List<SipResponse>> map = new HashMap<String, List<SipResponse>>();

    public SipResponseCollection() {
    }

    public boolean contain(String callId, int statusCode) {
        List<SipResponse> list = map.get(callId);  //pop null exception in linux amd64 machine but right for windows machine. callId is not null.
        if(list==null)
            return false;
        for (SipResponse sipResponse : list) {
            if (sipResponse.getStatusCode() == statusCode)
                return true;
        }

        return false;
}
}

在 new SipResponseCollection() 之后,如果 volatile 映射可以为空?我在不同的机器上运行,一台机器提示空异常。但删除关键字后: volatile ,一切正常。为什么?

ps:没有任何公共方法可以将地图设置为空。

4

3 回答 3

2

不,它不可能null——除非你设法从构造函数中泄漏。this你似乎没有这样做。

如果您向我们展示了更多代码,例如触发 的代码NullPointerException,那么您的问题可能会有更实质性的内容。

请注意,您的字段不是final这样的可能性仍然存在,即该字段从您的程序中的任何位置都被清空。

于 2013-05-30T09:37:24.853 回答
0

通过您的描述和代码,我看不出任何问题。

正如@Marko Topolnik 提到的:

将您的 volatile map 更改为 final,看看会发生什么。

于 2013-05-31T05:41:27.660 回答
0

line 可以通过两种方式 - map 可以为 null,get() 可以通过 NPE。我提供了一些理论,但它们涉及的实际代码与您编写的代码不同。

  • 那是其他 Map 而不是 HashMap,或者您有一些不支持空键的奇怪退化 HashMap。

Map.get() 可以对空键进行 NPE,但 HashMap 的实现不能。您是否在两者上运行相同的 JVM 实现?好像有点牵强。你确定 callId 不为空吗?

  • 您在初始化程序运行之前调用 contains() 。

实例初始化器在构造函数完成后发生。如果你:

  • 在构造函数中调用 contains(),或
  • 进行调用,将对象泄漏给调用 contains() 的对象

地图尚未初始化,将为空。

于 2013-05-31T02:39:46.763 回答