객체가 null이라면 뒤의 구문을 실행하지 않는 연산자
객체가 null이 아니라면 그대로 사용하지만 null이라면 우측의 객체로 대체되는 연산자
참조연산자를 사용할 때 null 여부를 컴파일시 확인하지 않도록 하여 런타임시 null pointer exception이 나도록 의도적으로 방치하는 연산자
fun main() {
var a:String? = null
println(a?.toUpperCase())
println(a?:"default".toUpperCase())
println(a!!.toUpperCase())
}
null
DEFAULT
Exception in thread "main" java.lang.NullPointerException
at FileKt.main (File.kt:6)
at FileKt.main (File.kt:-1)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (:-2)
null safe 연산자는 스코프 함수와 사용하면 더욱 편리하다.
null을 체크하기 위해 if문 대신 사용하면 편리한 기능이다.
fun main() {
var a: String? = "up"
a?.run{
println(toUpperCase())
println(toLowerCase())
}
}
메모리상의 서로 다른 곳에 할당된 객체의 내용이 같을 때
a==b
서로 다른 변수가 메모리상의 같은 객체를 가르킬 때
a===b
-> 코틀린의 모든 클래스가 내부적으로 상속받는 'Any'라는 최상의 클래스의 equals()함수가 반환하는 Boolean 값으로 판단하게 된다.
기본 자료형에는 자료형의 특징에 따라 equals() 함수가 이미 구현되어있지만 커스텀 클래스를 만들때는 아래처럼 equals를 상속받아 동일성을 확인해주는 구문을 별도로 구현해야 한다.
open fun equals(other: Any?): Boolean
fun main() {
var a = Product("콜라", 1000)
var b = Product("콜라", 1000)
var c = a
var d = Product("사이다", 1000)
println(a==b) // 내용동일성 true
println(a===b) // 객체동일성 false
println(a==c) // 내용동일성 true
println(a===c) // 객체동일성 true
println(a==d) // 내용동일성 false
println(a===d) // 객체동일성 false
}
class Product(val name:String, val price:Int) {
override fun equals(other: Any?): Boolean {
if(other is Product)
{
return other.name == name && other.price == price
} else {
return false
}
}
}