【问题标题】:NPE in java.util.LinkedList addBefore methodjava.util.LinkedList addBefore 方法中的 NPE
【发布时间】:2010-10-25 15:22:20
【问题描述】:

不知何故,JDK 1.6.0_14 出现空指针异常:

HttpSession session = request.getSession(true);
LinkedList<MyObject> list = (LinkedList<MyObject>) session.getAttribute(MY_LIST_KEY);
....
list.addFirst( new MyObject(str1, str2, map) );

然后,我明白了:

 at java.util.LinkedList.addBefore(LinkedList.java:779)

方法如下:

private Entry<E> addBefore(E e, Entry<E> entry) {
    Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
    newEntry.previous.next = newEntry;//this line NPEs
    newEntry.next.previous = newEntry;
    size++;
    modCount++;
    return newEntry;
}

被调用

public void addFirst(E e) {
    addBefore(e, header.next);
}

是否有任何奇怪的方式可以序列化/反序列化列表以破坏标题条目以导致这种情况发生?我不明白这怎么可能失败。

这里是LinkedList的序列化方法

private void writeObject(java.io.ObjectOutputStream s)
    throws java.io.IOException {
    // Write out any hidden serialization magic
    s.defaultWriteObject();

    // Write out size
    s.writeInt(size);

    // Write out all elements in the proper order.
    for (Entry e = header.next; e != header; e = e.next)
        s.writeObject(e.element);
}

private void readObject(java.io.ObjectInputStream s)
    throws java.io.IOException, ClassNotFoundException {
    // Read in any hidden serialization magic
    s.defaultReadObject();

    // Read in size
    int size = s.readInt();

    // Initialize header
    header = new Entry<E>(null, null, null);
    header.next = header.previous = header;

    // Read in all elements in the proper order.
    for (int i=0; i<size; i++)
        addBefore((E)s.readObject(), header);
}

【问题讨论】:

    标签: java serialization weblogic jdk1.6


    【解决方案1】:

    我的猜测是在多个线程之间不正确地共享列表。我猜这个列表正在被两个不同的线程同时修改。

    【讨论】:

    • 如何使 head 元素无效?我在这里看不到任何让标头为空的代码路径。
    • @Stefan Kendall,如果 2 个线程同时调用 readObject()addFirst() 并且第一个块就在 header.next = /* right here*/ header.previous = header; 你会有这样的情况。
    • 嗯,这似乎是合理的。我将切换到同步列表并重新测试。很好的抓地力。
    【解决方案2】:

    很可能,(LinkedList&lt;MyObject&gt;) session.getAttribute(MY_LIST_KEY) 返回了 null
    更新: 正如 cmets 中正确指出的那样,getAttribute() 不能在此处返回 null,否则 stacktrace 将不会t 指向LinkedList 的内部。所以,我的建议是错误的。

    【讨论】:

    • 堆栈跟踪将指向他自己的代码,而不是 LinkedList 类中的一行。
    • 如果列表为空,则 NPE 不能来自列表 addBefore() 方法。
    • 抱歉,忽略了 :) 请忽略我的回答。
    猜你喜欢
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    • 1970-01-01
    相关资源
    最近更新 更多