В конечном счете я получил ответ, но он озадачил меня некоторое время.
То, почему следующее кодирует, бросает NullPointerException, когда выполнено?
import java.util.*;
class WhyNullPointerException {
public static void main( String [] args ){
// Create a map
Map<String,Integer> m = new HashMap<String,Integer>();
// Get the previous value, obviously null.
Integer a = m.get( "oscar" );
// If a is null put 1, else increase a
int p = a == null ?
m.put( "oscar", 1) :
m.put( "oscar", a++ ); // Stacktrace reports Npe in this line
}
}
Потому что m.put
возвращает null
(что указывает на отсутствие "предыдущего" значения), пока вы пытаетесь присвоить его int
. Замените int p
на Integer p
, и все заработает.
Это указано в JLS 5.1.8:
5.1. 8 Преобразование без упаковки
Во время выполнения преобразование без упаковки происходит следующим образом:
- Если r является
null
, преобразование без упаковки выбрасываетNullPointerException
Не связанное с проблемой, просто побочное предложение с DRY в уме, рассмотрите возможность написать это так:
Integer p = m.put("oscar", a == null ? 1 : a++);
Это немного более читабельно :)
Вы назначаете int p
возвращаемому значению m.put ()
. Но put ()
возвращает null
в этой ситуации, и вы не можете присвоить int
null
.
Из документации Javadocs для HashMap.put ()
:
Возвращает: предыдущее значение, связанное с указанным ключом, или null, если не было отображение для ключа.