문제

나는 항상 JVM이 왜 당신에게 말하지 않는지 궁금했습니다 어느 포인터 (또는 더 정확하게, 변수)는 NullPointerException 던져졌다.

불쾌한 선에는 종종 오류를 일으킬 수있는 수많은 변수를 포함 할 수 있기 때문에 줄 번호는 충분하지 않습니다.

이러한 예외 메시지를 더 유용하게 만드는 컴파일러 또는 JVM 플래그가 있습니까?

도움이 되었습니까?

해결책

이름이 없을 때 항상 불이행이 발생하기 때문입니다. 값은 피연산자 스택에로드 된 다음 해석을 해소하는 JRE OPCODE 중 하나로 전달됩니다. 그러나 피연산자 스택에는 널 값과 연결할 이름이 없습니다. 그것이있는 것은 'null'입니다. 영리한 런타임 추적 코드를 사용하면 이름이 도출 될 수 있지만 값이 제한된 오버 헤드가 추가됩니다.

이로 인해 NULL 포인터 예외에 대한 추가 정보를 켜는 JRE 옵션이 없습니다.

이 예에서, 참조는 로컬 변수 이름에 매핑되는 로컬 슬롯 1에 저장됩니다. 그러나 부대는 invokevirtual 명령에서 발생하는데,이 명령은 스택에 '널'값 만 볼 수있는 다음 예외를 던진다.

15 aload_1
16 invokevirtual #5 

똑같이 유효한 배열 부하와 피로가 이어질 수 있지만이 경우 'null'값에 매핑 할 이름은 없으며 다른 값의 색인 만 있습니다.

76 aload    5
78 iconst_0
79 aaload
80 invokevirtual #5

각 명령에 정적으로 이름을 할당 할 수는 없습니다.이 예제는 많은 바이트 코드를 생성하지만 DeReference 명령이 OBJA 또는 OBJB를받을 수 있으며 올바른 것을보고하려면이 역동적으로 추적해야합니다. 두 변수 모두 동일한 DeReference 명령으로 흐르기 때문에 :

(myflag ? objA : objB).toString()

다른 팁

코드를 지정하면 네이티브 포인터 수학 일뿐입니다. 기본 코드의 포인터가 Null이면 예외가 발생합니다. 어셈블리가 원래 변수로 되돌아가는 것은 치명적인 성능에 영향을 미치며 JIT가 생성 된 코드를 다양한 레벨로 최적화하는 것을 고려할 때 종종 불가능합니다.

한 줄에서 여러 메소드 호출을하는 대신 여러 줄로 라인을 나누거나 해당 라인에서 중단 점을 설정하고 디버거로 라인을 통과하면 어떤 참조가 널리 어울리는 지 알 수 있습니다.

만약에

불쾌한 선에는 종종 오류를 일으킬 수있는 수많은 변수를 포함 할 수 있기 때문에 줄 번호는 충분하지 않습니다.

그런 다음 제안합니다 :

  1. 그 라인을 하나 이상의 줄로 나누고 가능한 NullPointerException-임시 변수에 대한 생성 값.
  2. 디버거를 사용하고 문제를 일으키는 것을 찾을 때까지 각 방법 호출을 밟습니다.

불행히도 이것은 Java가 작동하는 방식입니다.

이것이 "당신의"코드 인 경우

if (foo == null) {
  throw new NullPointerException("foo == null");
}

foo를 할당 한 직후. FOO가 매개 변수 인 경우 메소드 본문의 시작 부분에서 즉시 확인하고 대신 불법 행위를 던지십시오.

이것은 문제를 명확히하는 데 도움이 될 것입니다.

예외의 정확한 원인을 얻기 위해 디버깅 할 때 Eclipse에서 NULL 포인터 예외에 중단 점을 추가 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top