var
- 가변
val
- 불변
var
/ val
)를 명시해주어야 한다.val
로 만들고 필요한 경우 var
로 변경하여 사용하자.boxing
/ unboxing
을 고려하지 않아도 된다.null이 들어갈 수 있다는 것을 알려주기 위해 타입 뒤에ㅐ ?
을 붙인다.
ex) <Long?>
null
이 들어갈 수 있는지 없는지를 처음부터 표시해줘야 한다.new
를 사용하지 않는다.fun startWithA(str: String): Boolean { // string에 ? 가 없으니까 널이 들어올 수 없으므로 바로 리턴이 가능하다.
return str.startsWith("A")
}
fun startsWithA1(str: String?) : Boolean {
if (str == null) {
throw IllegalArgumentException("null이 들어왔습니다.")
}
return str.startsWith("A")
}
fun startsWithA2(str: String?): Boolean? { //null 반환 가능
if (str == null) {
return null
}
return str.startsWith("A")
}
fun startsWithA3(str: String?): Boolean {
if (str == null) {
return false
}
return str.startsWith("A")
}
널인지 먼저 체크하고, 널이 아니면 실행해주는 연산자
ex1)
val name: String? = "솜사탕"
val length = name?.length
name
이 null
이 아니면 length
를 가져오고
null
이면 length
도 null
이 됨
즉, 널포인터 예외(NullPointerException
)를 방지하기 위한 연산자다.
ex2)
val user: User? = null
val username = user?.name
user
가 null
이면 → username
도 null
user
가 null
이 아니면 → user.name
호출됨
앞의 값이 null이면, 뒤의 값을 대신 사용해
ex)
val name: String? = null
val finalName = name ?: "기본값"
name
이 null
이니까 finalName
은 "기본값"즉, null에 대한 기본값(default)을 지정할 때 사용하는 연산자다.
ex)
val user: User? = getUser()
val nickname = user?.nickname ?: "손님"
user
가 null
이면 → "손님"
user.nickname
이 null
이어도 → "손님"
user.nickname
이 존재하면 → 그 값을 사용
변수에 null이 아닌 게 확실할 때 강제로 null이 아님을 단언하는 연산자
ex)
val name: String? = "솜사탕"
val length = name!!.length
name
이 null
이 아닐 거라고 믿고 length
호출만약 name
이 실제로 null
이면 예외(NPE
) 발생
val name: String? = null
val length = name!!.length // NullPointerException 발생!
정말 이 시점에서는 null일 리 없다! 라는 확신이 있을 때만 사용해야 한다.
테스트 코드, 간단한 샘플, 프레임워크 내부에서 절대 null이 아니도록 보장될 때
실무에서는 !!
를 피하는 게 일반적이다.
?.
, ?:
, requireNotNull()
, checkNotNull()
등을 사용하는 게 더 안전하고 명시적이다.
Kotlin에서 !!
와 관련된 안전한 대안 requireNotNull()
null이 아니어야 한다
고 명시적으로 검증하고,
null이면 IllegalArgumentException을 던져준다.
fun printName(name: String?) {
val safeName = requireNotNull(name) { "이름은 null이면 안 돼요!" }
println("이름은 $safeName")
}
name
이 null이면 → 예외 발생 (IllegalArgumentException
)
name
이 null이 아니면 → 정상 실행
!!
처럼 막 쓰지 않고 검증 + 메시지까지 가능해서 디버깅에 유리하고
안전하게 fail fast
(빨리 죽기) 원칙에 맞는다.