2014-09-30 3 views
0

Ниже приведен фрагмент кода в java.Null pointer with iterator.next

Collection contextPages = (Collection) getContextPages(); 
Iterator contextPageIter = contextPages.iterator(); 
while (contextPageIter.hasNext()) { 
    Page contextPage = (Page) contextPageIter.next(); 
    String result = contextPage.getResult();  // <-- Null pointer exception here 
    // Other stuff which this API does. 
} 

Этот код был в эксплуатации некоторое время. Но по какой-то причине мы нанесли нулевой указатель на String result = contextPage.getResult();.

Так выглядит, хотя мы сделали чек на hasNext(), метод next() возвращает null.

Одна из возможностей заключается в том, что сама коллекция имеет null, но возможно ли, что этот код может привести к нулевому указателю в многопоточной среде?

+0

Как правило, это не разрешено изменять коллекцию одновременно. Тем не менее, нет никакой гарантии, что это будет обнаружено в коллекции (хотя [оно попытается это сделать]] (https://stackoverflow.com/a/13549956/1392132)). Это поможет узнать точный класс 'contextPages'. – 5gon12eder

+0

_Anything_ может произойти, если коллекция не является потокобезопасной, а один поток изменяет коллекцию, а другой поток использует Iterator для коллекции. У вас есть причина подозревать, что другой поток может использовать коллекцию одновременно? –

ответ

2

Некоторые коллекции позволяют добавлять нуль, поэтому iter.next будет возвращать его, и когда вы его используете -> NPE

Чтобы продемонстрировать

@Test 
public void testNull() { 
    Collection<Object> c = new ArrayList<>(); 
    c.add(null); 
    Iterator<Object> iterator = c.iterator(); 
    Assert.assertTrue(iterator.hasNext()); 
    Object o = iterator.next(); 
    Assert.assertNull(o); 
} 

Так убедитесь, что вы не добавляете null ссылки на коллекции или чек на null перед использованием результата Iterator#next()

Page contextPage = (Page) contextPageIter.next(); 
String result = null; 
if(contextPage != null) { 
     result = contextPage.getResult(); 
} 

Там не должно быть никакой разницы между одно- и многопоточными приложениями, просто убедитесь, что вы не добавляете null.

0

Лучше проверить нуль перед использованием результата Iterator.next()

Попробуйте это -

Page contextPage = (Page) contextPageIter.next(); 
String result = null; 
if(contextPage != null) { 
     result = contextPage.getResult(); 
}