[java] 값을 할당 할 때 이상한 Java 3 진 동작. 이 일이 발생하기 위해 Java가 무대 뒤에서 무엇을하고 있습니까?

며칠 전, 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하고, boolfalse null이면 result변수 에 맞게 Long 값으로 unboxe 를 시도 하고 NPE를 발생시킵니다.

이렇게하면 :

Long result = bool ? Long.valueOf(intVal) : longVal

이 표현식은 이미 반환 된 상태 Long이므로 개봉 할 필요가 없으며 null값이 result변수에 성공적으로 할당됩니다 .

참고:

주석 섹션에서 논의 된 바와 같이, 이것이 발생하는 이유를 더 잘 이해하려면 JLS의 다음 섹션을 확인하십시오.


답변