Ответ 1
Похоже, что это компилятор, зависящий от @kdgregory.
Здесь моя java -версия:
java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11-402-10M3527)
Java HotSpot(TM) Client VM (build 20.4-b02-402, mixed mode)
С помощью этого кода я NPE в строке 9 на трассировку стека (который соответствует номеру физической линии в источнике)
public static void main(String[] args) {
String evilString = null;
System.out.println(new StringBuilder()
.append(
evilString.toLowerCase())); // <--- NPE here (line 9)
}
Итак, я немного глуб с помощью javap:
Это таблица номеров строк для основного, как показано javap -l
(таблица номеров строк показывает исходную строку: смещение команды
public static void main(java.lang.String[]);
LineNumberTable:
line 6: 0
line 7: 2
line 9: 12
line 8: 16
line 7: 19
line 10: 22
строка источника 9 начинается со смещения 12.
javap -c для демонстрации показывает следующее:
public static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
5: new #22; //class java/lang/StringBuilder
8: dup
9: invokespecial #24; //Method java/lang/StringBuilder."<init>":()V
12: aload_1 <--- closest line in the line number table
13: invokevirtual #25; //Method java/lang/String.toLowerCase:()Ljava/lang/String; <--- NPE here
16: invokevirtual #31; //Method java/lang/StringBuilder.append: (Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #35; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
22: return
Мое предположение: когда исключение попадает в invokevirtual со смещением 13, jvm просматривает ближайшую предыдущую запись в таблице номеров строк и помещает ее в трассировку стека.