==과 ===의 차이는 ==는 값만 비교하는 것이고 ===는 값과 주소를 모두 비교하는 것이다.
fun main() {
val a: Int = 128
val b = 128
println(a==b) // true
println(a===b) // true
val c: Int? = 128
val d: Int? = 128
println(c==d) // true
println(c===d) // false
}
위 두 변수는 각각 Int 타입으로 128을 저장하고 있다. 코틀린의 경우 Int 타입은 컴파일을 할 때 기본형으로 변환하여 저장하기 때문에 두 변수가 가리키고 있는 곳과 값은 동일하다. 반면 밑에 두 변수는 null을 허용하는 변수로 변수 생성시 객체 형태로 변수를 생성한다. 생성된 객체는 두 변수에 의해 각각 다른 객체의 주소로 가리켜지기 때문에 값을 비교하는 ==연산에선 true를 만들지만 주소를 비교하는 ===연산에서는 false를 비교한다.
여기서 약간에 기술적인 내용이 들어가는데 -128~127을 대입하여 보면 모두 true가 나온다. 코틀린은 작은 크기의 값은 캐시 메모리에 저장하기 때문에 밑에 두 변수가 모두 같은 주소를 가리키게 된다.