2010-10-25 3 views
3

Каким-то образом, я получаю исключения нулевого указателя здесь с JDK 1.6.0_14:NPE в java.util.LinkedList addBefore метод

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); 
} 

ответ

2

Мое предположение было бы неправильным совместным использованием списка по нескольким потокам. Я бы предположил, что список одновременно изменяется двумя разными потоками.

+0

Как это могло бы привести к недействительности элемента головы? Я не вижу здесь никакого кодового пути, который когда-либо позволял заголовку быть нулевым. –

+1

@Stefan Kendall, если 2 потока одновременно вызывают 'readObject()' и 'addFirst()' и 1-й блоки прямо в 'header.next =/* прямо здесь */header.previous = header;' у вас будет такой дело. – rsp

+0

Хм, это кажется разумным. Я переключусь на синхронизированный список и повторю проверку. Хорошая уловка. –

-2

Скорее всего, (LinkedList<MyObject>) session.getAttribute(MY_LIST_KEY) вернулся null.
Update: Как правильно указан в комментариях, null не может быть возвращен getAttribute() здесь, в противном случае StackTrace не будет указывать на внутренности LinkedList. Итак, мое предложение неверно.

+0

stacktrace будет указывать на свой собственный код, а не на строку в классе LinkedList. –

+0

, если список будет пустым, тогда NPE не может быть вызван из метода addBefore(). –

+0

Извините, не обратил внимания на это: Пожалуйста, проигнорируйте мой ответ. –