삼항 연산자(조건 연산자)를 안다면 이제는 사용할 때 어떤식으로 사용되며, 이 때 주의할 점은 무엇인지 알아보자.
모른다면 아래 블로그 글을 한번 읽고 오는 것을 추천한다.
https://ssdragon.tistory.com/4
위 이미지 처음 식에서 2번째와 3번째 피연산자 0과 0.5는 타입이 서로 다르다.
int와 double 형으로 되어있는데 계산을 한다면 자동 형변환이 되어서 int -> double 타입으로 바뀌게 된다.
즉, result에는 double 타입의 연산결과가 들어가게 된다.
이런 기본형 타입(primitive type)에서의 자동형변환은 프로모션(promotion)과 캐스팅(casting)이 있다.
또한 자바의 자료형은 기본형 타입(primitive type)과 참조형 타입(reference type)으로 나누어지며,
후에 래퍼 클래스(Wrapper Class)를 만나게 될 것인데 이것은 기본형 타입 데이터를 객체로 표현할 때 쓰는 것인데 이 기본형 타입을 래퍼 클래스로 만드는 과정을 박싱(Boxing)이라 하고, 반대는 언방식(UnBoxing)이라고 한다.
이 부분들도 글을 따로 올려서 정리해야겠다.
위에 적어놓은 지식이 없다면 지금 적은 것들을 이해하기 어려울지도 모른다.
위 사진을 보면 삼항 연산자(조건 연산자)로 조건을 실행하였는데 NullPointerException이 발생하였다.
이 예외는 값이 null인데 이용하여서 생긴 것이다.
예외의 발생 위치를 보면 7번째 줄인 삼항 연산자 부분이다.
이클립스라는 IDE로 실행하였는데 num1에 노란색 밑줄이 쳐져있다. 마우스를 갖다대면 다음과 같다.
null pointer access: this expression of type integer is null but requires auto-unboxing 라는 문구가 나온다.
null pointer가 접근되었다. 이 Integer(정수) 타입의 표현식은 null이지만 자동 언박싱(auto-unboxing)이 필요하다.
위 문구를 해석해보자.
Null pointer(널 포인터)라는 유효한 객체를 참조하지 않는 포인터를 접근했다.
이 Integer(정수) 타입의 표현식은 null 이지만 자동 언박싱(auto-unboxing)이 필요하다.
🤨 자동 언박싱이 왜 필요한가?
삼항 연산자는 boolean 값을 사용하여 다른 두 표현식 중 어떤 표현식을 평가할지 결정한다.
즉, 결과가 특정 타입으로 평가되는 표현식이다.
그렇기에 삼항 연산자의 타입을 결정해야하는데 이것은 공식 문서를 참고해보자.
Java 8 Language Specification 15.25.2 Numeric Conditional Expressions
위 공식문서를 번역하면 다음과 같다.
- 두 번째와 세 번째 피연산자의 타입이 같으면 그 타입이 조건 표현식의 타입이다.
- 만약 두 번째와 세 번째 피연산자 중 하나는 primitive 타입 T 이고, 다른 하나가 T를 박싱 형변환 결과라면, 조건 표현식 타입은 T이다.
공식문서 15.25-A ~ E의 표로 예시를 들자면
- check ? null : null 이면 타입은 null 이다.
- check ? Long : Long 이면 타입은 Long 이다.
- check ? Double : double 이면 타입은 double 이다.
- check ? int : Integer 이면 int 이다.
위와 같은 과정을 읽었으니 다시 한번 코드를 살펴보자.
여기서 삼항 연산자는 check ? 0 : num1 이다.
즉, int : Integer 이므로 Integer 타입이 언박싱이 되어 int : int 로 바뀌게 된다.
현재 num1 은 null 이므로 null을 언박싱한 값이 나오게 된다.
null 을 언박싱하면 NullPointerException이 발생하게 된다.
이렇게 과정이 있어서 NPE 이 발생하게 된 것이다.
🤔 그렇다면 이것을 해결하려면 어떻게 해야하나?
1. if문을 쓴다.
2. 삼항 연산자의 타입을 맞춰준다.
2번째와 3번째 피연산자 타입을 같게해주면 언박싱이 일어나지 않는다.
그래서 0을 Integer로 타입을 변환했다.
결론
삼항 연산자(조건 연산자)를 사용할 때 2번째와 3번째 피연산자 타입이 다를 뿐인데 예외가 발생해 실행이 안되는 경우 많으니 적어도 삼항 연산자(조건 연산자)는 어떨 때 형변환이 일어나는지 박싱·언박싱이 일어나는지 알고 쓰면 좋을 듯하다.
참조 문서
https://ko.wikipedia.org/wiki/%EB%84%90_%ED%8F%AC%EC%9D%B8%ED%84%B0
https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
'프로그래밍 > Java' 카테고리의 다른 글
Java(자바) API 문서 다운받기 (0) | 2022.01.11 |
---|---|
Java(자바) 환경변수 설정하기 (0) | 2022.01.11 |
Java란? (3) | 2022.01.11 |
Java 삼항 연산자(조건 연산자) - Conditional Operator (0) | 2022.01.05 |
Java(자바)를 꼭 배워야할까? (0) | 2022.01.03 |