코틀린은 변수를 사용할 때 반드시 값이 할당되어 있어야 한다는 원칙이 있다.
1. NULL
코틀린이 NPE에서 자유로울 수 있는 이유는 위 원칙에 따라 변수에 아예 NULL을 허용하지 않기 때문이다.
코틀린에서는 NULL 상태인 변수를 허용하려면 물음표(?) 기호를 사용해 선언해야 한다.
이 변수를 사용하는 순간 NULL을 검사하고 처리하는 방법까지 고려해야 한다.
2. 세이프 콜과 NON-NULL 단정 기호를 활용하여 NULL 허용 변수 사용하기
2-1) 세이프 콜 -> ?.
NULL이 할당되어 있을 가능성이 있는 변수를 검사하여 안전하게 호출하도록 도와주는 기법
println("str: $str1 length: ${str1?.length}")
str1이 null이 아니면 멤버변수인 length에 접근해 출력하고, 아니면 length에 접근하지 않고 null을 출력한다.
2-2) NON-NULL 단정 기호 -> !!.
NON-NULL 단정 기호는 NPE를 강제 발생시킬 수 있다.
변수에 할당된 값이 NULL이 아님을 단정하므로 컴파일러가 NULL 검사 없이 무시하기 때문에 변수에 NULL이 할당되어 있어도 컴파일은 잘 진행된다. 하지만 실행중에 NPE가 발생한다 ㅠ_ㅠ
println("str: $str1 length: ${str1!!.length}")
NPE 강제 발생
3. 세이프 콜과 엘비스 연산자를 활용해 더 안전하게 사용하기
3-1) 엘비스 기호 -> ?:
변수가 NULL인지 아닌지 검사해 NULL이 아니면 왼쪽 식, NULL이면 오른쪽 식을 실행한다.
println("str: $str1 length: ${str1?.length ?: -1}")
str1이 null이 아니면 length에 접근, 아니면 -1출력
4. 자료형 변환
코틀린에서는 자료형이 다르면 비교/연산을 할 수 없다.
변환함수를 거쳐야 한다.
만약 표현식에서 자료형이 서로 다른 값을 연산하면 자료형의 범위가 더 큰 자료형으로 자동 형 변환하여 연산한다.
5. 이중 등호와 삼중 등호
(기본형과 참조형 자료형의 비교원리)
5-1) 이중등호(==) -> 단순히 값만 비교
5-2) 삼중등호(===) -> 값과 상관없이 참조 주소를 비교
5-3) 기본형과 참조형 저장
byte, short, int, float, double 등 기본형은 참조형으로 선언되지만 최적화 과정에서 코틀린 컴파일러에 의해 기본형으로 변환된다.
하지만 기본형이 아닌 null을 허용한 변수 등은 기본형으로 변환되지 않고 참조형으로 저장된다.
val a : Int = 128
val b : Int = 128
val c : Int? = 128
a==b -> true
a===b -> true
a==c -> true
a===c -> false
a,b는 기본형으로 변환되어 스택에 128이라는 값 자체를 저장하지만,
c는 참조형으로 힙 영역에 저장되므로 c에는 128이 아닌 참조 주소가 저장되어 있다.
val a : Int = 128
val c : Int? = a
val d : Int? = a
val e : Int? = c
c==d -> true
c===d -> c와 d는 서로 다른 128을 갖는 참조 주소를 갖고 있으므로 false
e===c -> 값의 내용도 같고 참조된 객체(주소)도 동일하므로 true
6. 저장되는 값이 128보다 작으면 그 값은 캐시에 저장되어 참조된다.
코틀린에서 참조형으로 선언한 변수의 값이 -128~127 범위에 있으면 캐시에 그 값을 저장하고 변수는 캐시의 주소를 가리킨다.
val a : Int = 128
val b : Int = 127
a는 스택에 128 값 자체를 저장하고,
b는 캐시에 128 값을 올리고 b에는 캐시의 주소를 참조하게 된다.
따라서,
val c : Int? = 127
val d: Int? = 127
b===c -> true
b===d -> true
이게된다 깍!
7. 자료형 검사하기 (is 키워드)
7-1) 변수 is 자료형
num is Int -> 맞으면 true 아니면 false
7-2) 스마트 캐스트
변수의 자료형을 검사한 다음 그 변수를 해당 자료형으로 스마트 캐스트 하는 기능도 있음.
val x : Any
x = "Hello"
if ( x is String) {
println(x.length)
}
x를 어떤형이라도 될 수 있는 Any형으로 선언
Hello 대입. 아직 자료형 Any.
x is String에서 String형으로 스마트캐스트.
8. Any형
코틀린 최상위 기본 클래스로 어떤 자료형이라도 될 수 있는 특수한 자료형
코틀린의 모든 클래스는 이 Any형이라는 슈퍼클래스를 가진다.
자료형이 특별히 정해지지 않은 경우에 사용한다. -> 언제든 필요한 자료형으로 자동 변환 할 수 있다. -> 묵시적변환
8-1) Any형의 실무 적용
fun main() {
checkArgs("Hello") // 문자열을 인자로
checkArgs(5) // 숫자를 인자로 넣음
}
fun checkArgs(x : Any) {
if(x is String) {
println("x는 문자열이당")
}
if(x is Int) {
println("x는 정수당")
}
}
checkArgs()는 매개변수로 Any형을 입력받아 들어오는 인자의 자료형에 따라 문자열 혹은 정수형으로 변환하여 처리한다.
'Deperecated > Kotlin' 카테고리의 다른 글
두잇 코틀린 프로그래밍 공부 <1강> (0) | 2020.06.12 |
---|---|
코틀린 - 고차함수와 람다식2 (고차함수, 람다식 사례) (0) | 2020.04.10 |
코틀린 프로젝트 구성 (0) | 2020.04.07 |
코틀린 - 상수 (0) | 2020.02.18 |
코틀린 - 코틀린 컬렉션 (0) | 2020.02.05 |