2014-01-31 5 views
0

Существует множество вопросов о SO об исключении NullPointerException, возникающем из-за распаковки, особенно при выполнении чего-то вроде int k = ... с объекта Integer. Я понимаю этот вопрос. Мой вопрос об анализе потоков данных:Предупреждение о неполадке Idea Intellij, похоже, не основано на анализе потока данных

волнистых желтая линия появляется, когда я делаю следующее:

HashBiMap<String, Integer> myMap = ... ; // some method populates a Guava HashBiMap 
for (String s : myMap.keySet()) { 
    int i = myMap.get(s); // Intellij issues warning here about NullPointerException 
} 

предупреда говорит, что на основе анализа потока данных, Intellij считает, что NullPointerException может быть сгенерирован во время выполнения , Предупреждение, однако, уходит, когда я изменить код выше для итерации следующим образом:

for (Map.Entry<String, Integer> entry : myMap.entrySet()) { 
    String s = entry.getKey(); 
    int i = entry.getValue(); 
} 

Насколько я могу видеть, как итерации имеют один и тот же поток данных, и ни один не должен выдавать никаких предупреждений (или оба должны выдавать то же предупреждение). Какая разница между потоками данных двух способов итерации над картой?

+0

Карта может возвращать null, если для ключа нет значения, null не может преобразовать в int ... NPE выбрасывается. –

+2

Проверки, вероятно, основаны на внешних аннотациях, созданных JetBrains. Может быть, они документируют результат «Map.get()» как значение NULL, а «Map.Entry.getValue()» как недействительный? –

+0

Ах, да, это возможно! Я не был уверен, что мне не хватает чего-то очевидного. Я буду ждать более определенного ответа, однако, прежде чем обвинять желтую строку squiggly в моей любимой IDE. –

ответ

1

Насколько я вижу, обе итерации имеют один и тот же поток данных, и ни одно из них не должно выдавать никаких предупреждений. Какая разница между потоками данных двух способов итерации над картой?

Я считаю, что разница в том, что итератор на entrySet() предполагается (по DFA, аннотаций, или просто явно), чтобы возвращать только полные записи, то есть пары ключ-значение, где значение никогда не null. Итерация над keySet() и вытягивание значений отдельно друг от друга немного отличается. Рассмотрим параллельную карту: значение можно удалить после того, как ключ будет извлечен, но перед вызовом get().

Это предположение, похоже, не задерживается в вашем случае, поскольку документация для HashBiMap указывает, что и ключи, и значения null поддерживаются.

+0

+1 для использования параллельного сценария. Не думал об этом вообще. –

+0

Итератор в 'entrySet()' возвращает только полные записи, которые могут содержать любое значение для 'Integer', включая' null'. –