불로구

[코틀린 기초] 5. 자료형 비교 & 변환 본문

프로그래밍/코틀린

[코틀린 기초] 5. 자료형 비교 & 변환

맹이맹이 2021. 2. 9. 08:19
반응형

코틀란의 자료형은 모두 참조형으로 선언된다고 예전에 포스팅한적이 있다.

그럼 정말 참조형만 사용할까?

아니다.

 

컴파일을 거쳐가며 Int, Long, Short와 같은 자료형은 기본형으로 변환이 된다.

그렇게 때문에 연산을 할 경우 자료형을 동일하게 변환을 시켜줘야 한다.

 

자바의 경우 자동 형변환이 있다.

예를 들어..

int a = 10;    ,   double b = a; 라고 선언했을 경우  b의 값을 10.0으로 a의 10이 double타입으로 변환되어 들어간다.

 

그럼 자바와 비슷한 코틀린에서는?

코틀린에서는 자료형이 다르면 함수를 사용해야 한다.

fun main(){
    val a: Int = 10
    val b: Double = a
}

이렇게 선언하면 코틀린에서는 자료형 불일치 오류 ( Type Mismatch )가 발생한다.

 

그럼 어떻게 변환하는가?

- toByte, toFloat, toLong, toDouble, toShort, toChar, toInt 메서드를 사용하면된다.

fun main(){
    val int_a = 10
    val double_a = 10.0
    val float_a = 10.0f
    val byte_a = 10
    val char_a = 'h'

    val b:Int = double_a.toInt()
    val c:Double = int_a.toDouble()
    val d:Byte = float_a.toByte()

    println(b)
    println(c)
    println(d)
}

이렇게 사용할 수 있다.

 

그런데 만약 표련식에서 자료형이 서로 다른데 연산을 수행하면 어떻게 될까?

예를 들어 val sum = 3L + 10; 이렇게 Long + Int의 경우 범위가 큰 자료형으로 자동 형 변환하여 연산한다.

즉, sum은 Long타입이 된다.

 

 

그럼 이번에는 기본형과 참조형 자료형의 비교 원리를 알아보자

비교방법으로는 총 3가지가 있다.

1. ==

2. ===

3. equals

1번의 경우는 순수 값만을 비교한다.

2번과 3번의 경우는 참조대상을 비교한다.

fun main(){
    val a: Int = 128
    val b: Int = 128
    println(a==b)  // true
    println(a===b)  // true

    val d: Int? = 128
    println(b==d) // true
    println(b===d) // false

    var k: Int = 128
    val l: Int? = k
    val m: Int? = k
    val n: Int? = l
    println(l == m) // true
    println(l === m) // false
    println(l === n) // true

    val str1: String = "Hello"
    val str2: String = "Hello"
    println("=============")
    println(str1 == str2) //true
    println(str1 === str2) //true
    println(str1.equals(str2)) //true
}

a와 b는 참조형으로 선언되었지만 컴파일러에 의해 기본형으로 변환되고 JVM 스택 영역에 주소대신 값이 저장이된다.

그렇기 때문에 ==,===모두 true가 나온다

하지만 d의 경우 null을 허용한 참조형으로 저장되기 때문에 128을 가리키는 주소가 저장되고 주소의 정보다 다르기 때문에 값을 비교하는 ==의 경우 true가 반환되지만 ===경우 참조 주소가 달라 false가 반환된다. 

 

*** 근데 여기서 중요한게 있다 ***

코드에는 128이란 값을 사용했다. 만약 -128 ~ 127 사이 값을 사용한다면?

- 캐시에 값을 저장하고 변수는 캐시의 주소를 가리키게 된다. -> 성능을 더 좋아지게 만들기 때문

- 이경우 값이 스택에 저장되는 것이 아니라 캐시의 주소를 참조함으로 ===비교시 true가 된다 ( 같은 주소를 참조 )

var num1: Int = 128
var num2: Int? = 128
println(num1 === num2) // false 
println(num1 == num2) // true
반응형
Comments