[Kotlin] Android 톺아보기 2-4. 자료형 비교, 검사, 변환

이소은·2022년 9월 14일
0

Android 기본기 잡기

목록 보기
6/9

어느덧 자료형 이야기의 마지막이다. 자료형을 비교하고, 검사하고, 변환하는 방법을 끝으로 자료형에서 탈출해보자.


자료형 변환하는 법!

Kotlin에서는 자료형이 서로 다른 변수를 비교하거나 연산할 수 없다. 예로 Int형 변수와 Long형 변수를 서로 더할 수 없다. 따라서 Kotlin에서는 자료형이 서로 다른 변수를 같은 자료형으로 만들어야 연산이 가능하며, 이때 변환 함수를 사용한다. (Java에서는 자료형이 서로 다르면 자동으로 변환되었다.)


// java code
int a = 1;
double b = a;

Java에서는 위와 같이 int형 변수 a 를 double형 변수 b에 넣을 수 있다. 이는 a에 할당된 1이라는 값이 자동으로 int형에서 double형으로 변환되어 1.0이 b에 할당되었기 때문이다. 이처럼 Java에서는 서로 다른 자료형을 연산할 때 작은 자료형 (int)에서 큰 자료형 (double) 으로 자동 형 변환이 된다.


val a: Int = 1
val b: Double = a // error
val b: Double = a.toDouble() // 가능
val c = 1L +3 // Long으로 형변환됨

Kotlin에서 Java처럼 동일한 코드를 쓰면 바로 에러가 나버린다.. Kotlin에서는 자료형이 다른 변수에 재할당되면 형 변환이 일어나는 것이 아니라, 오류가 뜬다. 따라서 자료형을 변환하여 할당하고 싶으면 toDouble()과 같은 자료형 변환 메서드를 사용해야 한다. 표현식에서는 자료형이 서로 다른 값을 연산하면 범위가 큰 자료형으로 자동 형 변환되어 연산된다.



기본형과 참조형에서 자료형을 어떻게 비교할까?

자료형을 비교할 때는 단순히 값만 비교하는 방법과 참조 주소까지 비교하는 방법이 있다.

  1. 값만 비교: == 사용 (값이 동일하면 true)
  2. 참조 주소 비교: === 사용 (값이 같더라도 참조 주소가 다르면 false)

val a: Int = 128
val b = a

val c: Int? = a
val d: Int? = a
val e: Int? = c

println(a===b) // true
println(c===d) // false
println(c===e) // true

위의 코드는 언제나 헷갈리는 참조형과 기본형의 비교 예시이다. a와 b는 Int형이나 컴파일러에 의해 기본형으로 바뀌므로 스택에 128이 저장된다. 즉, a 와 b는 값도 같고 참조주소도 같다.


반면 c, d, e는 모두 null을 허용해 참조형이다. 허나 c 와 d는 128을 가리키는 각각 다른 객체의 참조 주소를 가리켜서 === 의 결과가 false가 나온다. e는 참조형 c의 주소가 저장되어 c와 e는 ===의 결과가 true이다.


주의!!!

위에서 c와 d는 128의 값을 갖는 각각 다른 객체를 갖기에 ===의 결과가 false이다. 다만, Kotlin에서는 참조형으로 선언한 변수의 값이 -128 ~ 127 사이에 있으면 스택이 아닌 캐시에 저장해 캐시의 주소를 가리킨다.

따라서 a의 값이 100이었다면 a, b, c, d 모두 === 으로 비교해도 같은 주소를 참조하여 모두 true가 된다.



스마트 캐스트가 뭐야?

만약 어떤 값이 정수일 수도 있고 실수일 수도 있다면 어떻게 해야 할까? 그때마다 자료형을 변환하기는 매우 귀찮으므로 Kotlin의 컴파일러는 자동으로 형 변환을 해준다. 이것을 "스마트 캐스트"라고 한다. 대표적인 예로 Number형이 있다. Number형을 사용하면 숫자를 저장하는데 쓸 특수한 자료형 객체를 만든다. 즉, 변수에 저장되는 값에 따라 정수형이나 실수형 등으로 자동 형변환이 되는 것이다.


fun main(){
  var test: Number = 12.2
  println(test) //12.2
  
  test = 12
  println(test) //12
}

위와 같이 test 변수는 Number형을 타입으로 가져서 정수, 실수 모두 대입이 가능하며 값에 맞게 자동으로 형 변환이 된다.



자료형 검사하기

변수의 자료형은 is 키워드로 알아낼 수 있다. is는 왼쪽 항의 변수가 오른쪽 항의 변수와 같으면 true, 아니면 false를 반환한다.

fun main(){
  val num = 128
  if(num is int){
    println("Int")
  }else if(num !is Int){
    println("Not Int")
  }
}//결과는 Int

참고!!!

변수의 자료형으로 Any를 사용하면 자료형을 결정하지 않은채로 변수를 선언할 수 있다. Any형은 Kotlin의 최상위 기본 클래스로 어떤 자료형이라도 될 수 있는 특수한 자료형이다. Int, String, 사용자가 만든 클래스까지 모든 클래스의 부모인 슈퍼클래스이다. 이때 is로 자료형을 검사하면 검사한 자료형으로 스마트 캐스트된다.

이렇게 Any형을 필요한 자료형으로 자동 형변환시키는 것을 묵시적 변환이라고 한다.


val x: Any
x = "Hello"
if(x is String){
  println(x.length) // String으로 스마트캐스트됨
}

as 키워드로도 스마트 캐스트가 가능하다. 단, as는 형 변환이 가능하지 않으면 예외를 발생시킨다.

val x: String? = y as? String //y가 null이 아니면 String으로 형 변환되어 x에 할당



Reference

  • 이것이 안드로이드다 with Kotlin (고돈호 지음, 한빛미디어)
  • Do it! 코틀린 프로그래밍 (황영덕, 이지스퍼블리싱)
profile
안드로이드 개발자

0개의 댓글