Nullability
•
자바에서는 Null 인 객체를 잘못 사용하며 NullPointerException(NPE)가 발생
•
이것을 방지하기 위해 메서드 최상단은 항상 Null 여부 체크가 필수
•
코틀린에서는 이것을 더욱 명확히 관리해줌
null이 될 수 있는 타입 vs null이 될 수 없는 타입
// 널이 될 수 있는 타입
val nullable: String?
// 널이 될 수 없는 타입
val notNull : String
Kotlin
복사
•
의문 혹은 불확실함을 나타내는 물음표(?)를 활용하여 nullable한 타입임을 나타냄
•
해당 타입의 경우 컴파일 시점부터 null check 가 진행됨
◦
not null type variable = nullable type variable : 컴파일 오류 발생
◦
nullable type variable = not null type variable : 가능
•
함수 파라미터, 응답타입 등이나 클래스의 생성자나 프로퍼티 정의에도 사용 가능
fun main() {
val nullablePerson: Person? =
if (System.currentTimeMillis() % 2 == 0L)
Person("Even", 22)
else
null
// if 검사 등으 로 특정 영역에서는 not null 타입처럼 사용 가능
if (nullablePerson?.age != null) {
println("짝수 시간에만 존재하는 사람의 나이는 : ${nullablePerson.age}")
}
// ?. 호출을 수행 : 값이 있는 경우는 호출 결과, 값이 없는 경우 null
println("짝수 시간에만 존재하는 사람의 나이는 : ${nullablePerson?.age}")
// !!. 호출을 수행 : 값이 없는 경우 NPE가 발생
println("짝수 시간에만 존재하는 사람의 나이는 : ${nullablePerson!!.age}")
}
== 결과 ==
짝수 시간에만 존재하는 사람의 나이는 : null
Exception in thread "main" java.lang.NullPointerException
at ch15.MainKt.main(Main.kt:19)
at ch15.MainKt.main(Main.kt)
Kotlin
복사
•
nullable 한 클래스 인스턴스에서의 3가지 호출 방법
◦
if 조건식으로 타입을 일시적으로 변경
◦
?. 호출로 호출하거나 혹은 null을 줌
◦
!!. 호출로 강제 호출을 하거나 혹은 NPE가 발생하도록 함
Elvis operator (엘비스 연산자)
•
?: (물음표 + 콜론)을 엘비스 연산자로 부름
•
nullable한 타입이 없는 경우 default value를 지정해주는 연산자
fun nullableToNotNull(s: String?): String = s ?: "default string"
fun nullableToNotNull(s: String?): String = getSomeNullableData()
?: Person("홍길동", 22)
Kotlin
복사
주의할 부분
•
플랫폼 타입(Platform type) : 자바 라이브러리 혹은 자바 코드에서 가져온 값의 null 여부를 체크할 수 없는 경우의 타입을 의미함
◦
null 관련된 표준 어노테이션이나 특정 어노테이션이 있는 경우 코틀린이 타입을 인식함
◦
플랫폼 타입은 개발자가 직접 해당 타입의 nullability를 지정해야 함
◦
자바 클래스의 값을 가져오는 경우 아래 두가지 모두 가능함
val name: String? = javaPerson.name
val name: String = javaPerson.name
Kotlin
복사
코틀린의 원시타입
•
코틀린은 원시타입과 래퍼타입을 구분하지 않음
•
코틀린은 자바 클래스 파일을 만드는 방식으로 동작하는데 상황에 따라 원시타입/래퍼타입을 넣어줌
◦
특별한 이유 없으면 원시타입
◦
nullable 하거나 제너릭에 쓰거나 라이브러리 호출 시에는 래퍼타입
숫자의 타입 변환
•
자바는 int와 long 간에 범위가 같으면 자동으로 변환을 수행하지만 코틀린은 직접 수행해 명시를 해줘야 함
val i:Int = 1
val l:Long = 1L
val ll:Long = i.toLong()
Kotlin
복사
•
toLong, toInt, toShort 등 다양한 변환함수 제공
Any, Any? : 최상위 타입
•
자바의 Object와 비슷한 코틀린의 Any 타입
•
Any는 not null 타입이며, Any?는 nullable한 값이며 null을 포함한 모든 값을 대입 받을 수 있음
Unit : 코틀린의 void 역할을 수행
fun printSomething(): Unit {
println("Something")
}
Kotlin
복사
•
자바에서 return 값이 없는 경우 void를 쓰듯이 코틀린에서는 Unit을 활용
•
하지만 Unit을 생략해도 됨
Nothing : 이 함수는 정상적으로 끝나는 케이스가 없음(Nothing)
fun fail(message: String): Nothing {
throw IllegalStateException(message)
}
fun main() {
val name = persons.find { it.age > 50 } ?: fail("50살이 넘는 사람이 없음")
}
Kotlin
복사
컬렉션과 배열
val list: List<Int>
val listOfNullable: List<Int?>
val nullableList: List<Int>?
val nullableListofNullable: List<Int?>?
Kotlin
복사
•
컬렉션 내에도 nullable 타입을 넣을 수 있으며, 컬렉션도 nullable 할 수 있음
수정 가능한(mutable) 컬렉션과 수정 불가능한(immutable) 컬렉션
•
수정 불가능한 컬렉션 : Collection 인터페이스의 구현체
◦
get, size, iterator, contains 등 읽는 기능만 제공
◦
생성 방법 : listOf(), mapOf(), setOf()
•
수정 가능한 컬렉션 : MutableCollection 인터페이스의 구현체
◦
Collection을 확장한 인터페이스로 위의 읽기 기능에 add, remove, clear 등의 추가, 삭제, 수정 등의 기능을 추가로 제공
◦
생성 방법:
▪
mutableListOf(), mutableMapOf(), mutableSetOf()