코린이 탈출기
02 변수와 자료형, 연산자 (02-3 자료형 검사하고 변환하기) 본문
02-3 자료형 검사하고 변환하기
코틀린은 변수를 사용할 때 반드시 값이 할당되어 있어야 한다는 원칙이 있지만, 만약 변수에 값이 없는 상태를 만들고 싶을 경우에는 어떻게 해야 할까요??
‘값이 없는 상태’를 null이라는 용어를 사용합니다. null을 할당하여 변수에 값이 없는 상태를 만들 수 있습니다. 코틀린에서는 null 상태인 변수를 허용하려면 물음표(?) 기호를 사용해 선언해야 합니다.
null을 허용하는 변수를 사용하려면 null을 검사하고 처리하는 방법까지 고려해야 하고, 필요한 자료형을 변환할 수도 있습니다.
null을 허용한 변수 검사하기
프로그램이 실행되는 도중에 값이 null인 변수에 접근하려 하면 NullPointException(NPE) 예외 오류가 발생합니다. 코틀린은 변수에 null을 허용하지 않아 이 문제를 미리 방지할 수 있습니다.
- 변수에 null 할당하기

위와 같이 타입에 물음표(?) 기호를 사용하지 않을 경우에는 null을 허용하지 않는다는 뜻입니다. 그렇게 때문에 만약 null을 할당하게 된다면 위와 같이 null에 빨간 줄로 표기사 되면서 NPE 예외 오류가 발생하게 됩니다.

변수에 null 할당을 허용하려면 자료형 뒤에 물음표(?) 기호를 명시해야 합니다. null 허용 여부에 따라 String과 String? 서로 다른 자료형입니다.
- 세이프 콜과 non-null 단정 기호를 활용하여 null을 허용한 변수 사용하기

위와 같이 문자열의 길이를 구하기 위해 str1.length를 사용할 경우, 변수에 문자열이 할당되어 있는 상태라면 길이를 구할 수 있겠지만 null이 할당되어 있는 상태라면 문자열의 길이를 구할 때 NPE가 발생할 것입니다.
이럴 경우 세이프 콜(.?)이나 non-null 단정 기호(!!)만 허용한다는 팁을 볼 수 있습니다.
세이프 콜이란 null이 할당되어 있을 가능성이 있는 변수를 검사하여 안전하게 호출하도록 도와주는 기법을 말합니다. 검사를 하고 값이 있으면 그 값을 읽고, 아무것도 들어 있지 않을 경우 null을 출력합니다.
non-null 단정 기호는 변수에 할당된 값이 null이 아님을 단정하므로 컴파일러가 null 검사 없이 무시합니다. 따라서 변수에 null이 할당되어 있어도 컴파일은 잘 진행됩니다. 하지만 null 상태라면, 실행 중에 NPE를 발생시킵니다.
- 조건문을 활용해 null을 허용한 변수 검사하기
조건문으로 null을 허용한 변수를 검사해도 됩니다. 즉, null을 허용한 변수의 null 상태 가능성을 검사하기만 하면 코틀린 컴파일러는 오류를 발생시키지 않습니다.
val length = if (str1 == null) -1 else str1.length
- 세이프 콜과 엘비스 연산자를 활용해 null을 허용한 변수 더 안전하게 사용하기
null을 허용한 변수를 조금 더 안전하게 사용하려면 세이프 콜(?.)과 엘비스 연산자 (?:)를 함께 사용하면 됩니다. 엘비스 연산자는 변수가 null인지 아닌지 검사하여 null이 아니라면 왼쪽식을 실행하고, null이면 오른쪽 식을 실행합니다.
위 조건문을 기호를 표현하는 방식이라고 생각하시면 됩니다.
val length = str1?.length ?: -1
엘비스 연산자의 경우 서버 통신을 할 데이터의 기본값을 정할 때 자주 사용한다고 합니다.
null에 대해 위와 같이 세이프콜이나 단정기호를 사용하는 이유는 컴파일러에게 알려주어 속도를 높여주기 위해서입니다.
자료형 비교하고 검사하고 변환하기
코틀린에서 서로 다른 자료형의 경우 비교하거나 연산할 수 없습니다. 자료형이 서로 다른 변수를 같은 자료형으로 만들어야 연산할 수 있습니다.
- 자료형 변환
코틀린에서는 자료형이 다르면 변환 함수를 사용해야 하지만 자바에서는 자료형이 서로 다르면 자동으로 변환됩니다.
코틀린에서는 자료형이 다른 변수에 재할당하면 자동 형 변환이 되지 않고 자료형 불일치 오류(Type Mismatch)가 발생합니다. 의도하지 않게 자료형이 변하는 것을 방지하기 위한 것입니다. 원하는 자료형으로 변환하는 방법은 .to자료형() 메서드를 사용하면 됩니다.

위와 같이 다양한 자료형으로 바꿀 수 있는 것을 볼 수 있습니다.
- 기본형과 참조형 자료형의 비교 원리
단순히 값만 비교할 때는 이중 등호(==)를 사용하고 참조 주소를 비교하려면 삼중 등호(===)를 사용합니다.
val a: Int = 123
val b: Int = 123
val c: Int? = 123
println(a==b) //true
println(a===b) //true
println(a==c) //true
println(a===c) //false
a, b는 123이라는 값이 기본형으로 변환되어 스택에 값 자체를 저장하기 때문에 값과 참조 주소가 같지만, c는 Int?형인 참조형으로 저장되므로 123이 저장된 힙의 참조 주소가 저장되어 있습니다. 그래서 값은 같지만 참조 주소는 다릅니다.
- 스마트 캐스트 알아보기
자료형이 바뀔 경우에는 컴파일러가 자동으로 형 변환을 하는 스마트 캐스트를 사용하면 됩니다.
- 자료형 검사하기
is는 왼쪽 항의 변수가 오른쪽 항의 자료형과 같으면 true, 아니면 false를 반환합니다.
val x: Any
x = "Hello"
if (x is String) {
print(x.length)
}
- as에 의한 스마트 캐스트
as로 스마트 캐스트할 수 있습니다. as는 형 변환이 가능하지 않으면 예외를 발생시킵니다.
val x: String = y as String
위의 경우 y가 null이 아니면 String으로 형 변환이 되지만, null이면 형 변환을 할 수 없으므로 예외가 발생합니다.
- 묵시적 변환
Any형은 자료형이 특별히 정해지지 않은 경우에 사용합니다. 코틀린의 Any형은 모든 클래스의 뿌리입니다. 즉, 코틀린의 모든 클래스는 바로 이 Any형이라는 슈퍼 클래스를 가집니다.
Any형은 무엇이든지 될 수 있기 때문에 언제든 필요한 자료형으로 자동 변환할 수 있습니다. 이것을 묵시적 변환이라고도 합니다. 즉, 함수와 판단문을 사용해 언제든지 필요한 자료형에 따른 역할을 지정하여 처리할 수 있습니다.
fun main() {
checkArg("Hello")
checkArg(12)
}
fun checkArg(x: Any) {
if (x is String) {
println("x is String")
}
if (x is Int) {
println("x is Int")
}
}
결과
x is String
x is Int
위와 같이 Any를 통해 여러 자료형의 인자가 들어올 수 있고, is로 자료형을 확인하여 자료형에 따른 원하는 동작을 작성할 수 있습니다.
'책 > Do it! 코틀린 프로그래밍' 카테고리의 다른 글
| 02 변수와 자료형, 연산자 (02-2 변수와 자료형) (0) | 2022.03.24 |
|---|---|
| 02 변수와 자료형, 연산자 (02-1 코틀린 패키지) (0) | 2022.03.23 |
| 01 코틀린 시작하기 (0) | 2022.03.17 |