공부 정리: Chapter02 변수와 자료형,연산자 - Section03 자료형 검사하고 변환하기
코틀린은 변수를 사용할 때 반드시 값이 할당되어 있어야 한다. 만약 값이 할당되지 않은 변수를 사용하면 코틀린에서 오류가 발생한다. 값이 없는 상태는 null이라고 부른다.
프로그램이 실행되는 도중에 값이 null인 변수에 접근하려 하면 NullPointerException(NPE) 예외 오류가 발생한다. 코틀린은 변수에 아예 null을 허용하지 않아 이 문제를 미리 방지할 수 있다. 변수에 null 할당을 허용하려면 자료형 뒤에 물음표(?) 기호를 명시해야 한다.
예를 들면, 변수의 null 허용 여부에 따라 String 혹은 String? 자료형을 사용할 수 있는데 이 둘은 서로 다른 자료형이다.
세이프 콜과 non-null 단정 기호 활용
세이프 콜(?.)이란 null이 할당되어 있을 가능성이 있는 변수를 검사하여 안전하게 호출하도록 도와주는 기법
non-null 단정 기호(!!)는 변수에 할당된 값이 null이 아님을 단정하므로 컴파일러가 null 검사 없이 무시한다. 따라서 변수에 null이 할당되어 있어도 컴파일은 잘 진행되지만 실행 중에 NPE를 발생시킨다.
세이프 콜과 엘비스 연산자를 활용
자료형 변환
코틀린에서는 자료형이 다르면 변환 함수를 사용해야 한다. 자바에서는 자료형이 서로 다르면 자동으로 변환되지만 코틀린에서는 자료형이 다른 변수에 재할당하면 자동 형 변환이 되지 않고 자료형 불일치 오류(Type Mismatch)가 발생한다.
코틀린에서는 자료형 변환 메서드(예를 들면 toDouble())를 이용하여 명시적으로 변환해주어야 한다.
만약 표현식에서 자료형이 서로 다른 값을 연산하면 자료형이 표현할 수 있는 범위가 큰 자료형으로 자동 형 변환하여 연산한다. (아래 코드 참조)
val result = 1L + 3 // Long형 + Int형 -> result는 Long형
기본형과 참조형 자료형의 비교 원리
a와 b는 참조형인 Int형으로 선언되었지만 코틀린 컴파일러에 의해 기본형으로 변환되어 저장된다. 프로그램을 실행하면 a와 b는 스택에 주소가 아닌 128이라는 값이 저장된다.
null을 허용한 변수 c와 d는 참조형으로 저장된다. 그래서 c와 d에는 서로 다른 128을 가리키고 있는 주소:A1과 주소:A2가 저장된다.
null을 허용한 e는 조금 다르다. 참조형으로 만들어진 e에는 c의 참조 주소인 주소:A1이 저장되므로 c와 e를 이중 등호와 삼중 등호로 비교한 값은 모두 true이다.
#저장되는 값이 128보다 작으면 그 값은 캐시에 저장되어 참조된다
코틀린에서는 참조형으로 선언한 변수의 값이 -128~127 범위에 있으면 캐시에 그 값을 저장하고 변수는 캐시의 주소를 가리킨다. 더 좋은 성능의 프로그램을 만들 수 있기 때문이다.
var a: Int? = 28
var b: Int? = 28
print(a === b) // true
위의 코드에서 28이라는 값은 스택이 아니라 캐시에 저장되고 a와 b는 캐시의 주소를 참조하게 된다.
명시적 형변환
명시적 형변환이란 사용자가 직접 데이터를 변경하는 것이다.
- as 키워드
as는 명시적 형변환이라고 볼 수 있다. as는 안전하지 않은 캐스트 연산자이고, as?는 안전한 캐스트 연산자이다.
as는 형 변환이 가능하지 않으면 예외를 발생시킨다.
val x: String = y as String
위의 경우 y가 null이 아니면 String으로 형 변환되어 x에 할당된다. y가 null이면 형 변환을 할 수 없으므로 예외가 발생.
null 가능성까지 고려하여 예외 발생을 피하려면 다음과 같이 물음표(?) 기호를 사용할 수 있다.
val x: String? = y as? String
묵시적 형변환
묵시적 형변환은 컴파일러가 자동으로 형 변환을 해주는 것이다.
1. is 키워드 (스마트 캐스트)
변수의 자료형을 알아내는 방법으로 is 키워드를 사용한다. 왼쪽 항의 변수가 오른쪽 항의 자료형과 같으면 true, 아니면 false를 반환한다. !is로 사용도 가능하다.
val num = 256
if (num is Int) {
print(num)
}
스마트 캐스트인 is는 임시로 묵시적 변환을 해주는 것이다. 임시이기 때문에 묵시적 변환된 객체는 상수로 만들어지고 사용되는 레벨에서 벗어나면 자동 삭제가 된다.
그래서 코틀린에서 is는 묵시적 변환의 한 종류이지만, 일반적인 묵시적 변환과는 다른 특성이 가진다.
그래서 책에서는 스마트 캐스트라고 따로 분류시킨 것이 아닐까라는 것이 카페 담당자의 의견.
2. Any
Any형은 자료형이 특별히 정해지지 않은 경우에 사용한다. 코틀린의 Any형은 모든 클래스의 뿌리이다. 모든 클래스가 Any형의 자식 클래스이다. 즉, 코틀린의 모든 클래스는 바로 이 Any형이라는 슈퍼클래스(Superclass)를 가진다.
Any는 모든 클래스의 최상위 클래스이므로 모든 객체를 담을 수 있고 Any형은 무엇이든 될 수 있기 때문에 언제든 필요한 자료형으로 자동 변환할 수 있다. 그래서 묵시적 변환이라고 볼 수 있는 것이다.