Deperecated/Kotlin

코틀린 기본 -2 (변수)

누알라리 2020. 4. 8. 16:07
코틀린은 변수를 사용할 때 반드시 값이 할당되어 있어야 한다는 원칙이 있다.

 

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형을 입력받아 들어오는 인자의 자료형에 따라 문자열 혹은 정수형으로 변환하여 처리한다.