며칠 전, Java가 어떻게 또는 왜 다음을 수행 할 수 있는지에 대한 문서를 찾을 수없는 매혹적인 시나리오를 만났습니다. 이 스 니펫은 단순한 버그 형태입니다.
@Test
public void test() {
boolean bool = false;
Integer intVal = Integer.valueOf(5);
Long longVal = null;
Long result = bool ? intVal : longVal;
System.out.println(" > " + result);
}
위의 스 니펫에서 :
bool = true이면 ‘5’값을 얻습니다.
그러나 bool = false이면 삼항 연산을 평가하려고 할 때 널 포인터 예외가 발생합니다. 인쇄 문이 아닙니다.
이 문제를 해결하려면 ‘result’를 다음과 같이 변경하십시오.
Long result = bool ? Long.valueOf(intVal) : longVal;
이렇게하면 내가 필요한 예상 동작이 나타납니다.
bool = true이면 ‘5’값을 얻습니다.
그러나 bool = false이면 ‘null’이됩니다.
이제 재미있는 부분은 이것을 일반적인 if / else 문으로 나누면 java가 컴파일 할 수 없다는 것입니다
longVal = intVal;
그러나 삼항 연산자를 통해 그것을 포착하지 못합니다. 그렇다면 Java는 원래 스 니펫에서 널 포인트로 만들기 위해 무엇을하고 있습니까?
(자바 11)
답변
이렇게하면 :
Long result = bool ? intVal : longVal
이 표현식은 a를 반환 long
하고, bool
false null
이면 result
변수 에 맞게 Long 값으로 unboxe 를 시도 하고 NPE를 발생시킵니다.
이렇게하면 :
Long result = bool ? Long.valueOf(intVal) : longVal
이 표현식은 이미 반환 된 상태 Long
이므로 개봉 할 필요가 없으며 null
값이 result
변수에 성공적으로 할당됩니다 .
참고:
주석 섹션에서 논의 된 바와 같이, 이것이 발생하는 이유를 더 잘 이해하려면 JLS의 다음 섹션을 확인하십시오.