
?fun strLenSafe(s: String?): Int =
s?.length ?: 0
fun main(args: Array<String>) {
val x: String? = null
println(strLenSafe(x)) // 0
println(strLenSafe("abc")) // 3
}
?.s?.method() if (s != null) s.method() else nullfun printAllCaps(s: String?) {
val allCaps = if (s != null) s.toUpperCase() else null
val allCaps: String? = s?.toUpperCase()
println(allCaps)
}
fun printAllCaps(s: String?) {
val allCaps: String? = s?.toUpperCase()
println(allCaps)
}
?:return 이나 throw 구문 또한 expression이므로, 엘비스 연산자에 사용가능하다.fun strLenSafe(s: String?): Int = s?.length ?: 0
class Address(val streetAddress: String, val zipCode: Int,
val city: String, val country: String)
class Company(val name: String, val address: Address?)
class Person(val name: String, val company: Company?)
fun printShippingLabel(person: Person) {
val address = person.company?.address
?: throw IllegalArgumentException("No address")
with (address) {
println(streetAddress)
println("$zipCode $city, $country")
}
}
as?foo as? Stringif (foo is String) foo as String else null?: 엘비스 연산자와 함께 많이 사용class Person(val firstName: String, val lastName: String) {
override fun equals(o: Any?): Boolean {
val otherPerson = o as? Person ?: return false
return otherPerson.firstName == firstName &&
otherPerson.lastName == lastName
}
}
fun main(args: Array<String>) {
val p1 = Person("Dmitry", "Jemerov")
val p2 = Person("Dmitry", "Jemerov")
println(p1 == p2) // true
println(p1.equals(42)) // false
}
asis 를 통해 미리 변환 가능한 타입인지 확인 해야한다.as 로 지정한 타입이 변환 불가능하다면, ClassCastException 이 발생!!foo!!if (foo != null) foo else throw NullPointerException()NOTE:
실제 널에 대해!!를 사용하면NullPointerException이 발생한다.
!!를 한줄에 여러번 쓰는 건 피해야 한다.
person.company!!.address!!.country
코드 몇번째 라인에서 발생했는지는 알 수 있으나, 자세히 어떤 값에서 발생했는지는 알 수 없다.
let 함수if (email != null) sendEmailTo(email)email?.let { sendEmailTo(it) }val person: Person? = getTheBestPersonInTheWorld()
if (person != null) {
sendEamilTo(person.email)
}
getTheBestPersonInTheWorld()?.let { sendEmailTo(it.email) }
lateinit varvar 여야 한다.lateinit property XXXX has not been initialized 라는 예외가 발생한다.class MyService {
fun performAction(): String = "foo"
}
class MyTest {
private lateinit var myService: MyService
@Before fun setUp() {
myService = MyService()
}
@Test fun testAction() {
Assert.assertEquals("foo",
myService.performAction())
}
}
fun String?.isNullorBlank(): Boolean =
this == null || this.isBlank()
fun main() {
println("".isNullOrBlank()) // true
println(null.isNullOrBlank()) // true
}
isNullOrBlank() 를 제공한다.fun <T> printHashCode(t: T) {
println(t?.hashCode())
}
fun main(args: Array<String>) {
printHashCode(null)
}
T 를 Any? 타입으로 추론한다.fun <T: Any> printHashCode(t: T) {
println(t.hashCode())
}
fun main(args: Array<String>) {
printHashCode(null) // Compile Erorr
}
// Type parameter bound for T is not satisfied: inferred type Nothing? is not a subtype of Any
@NotNull, @Nullable 과 같이 널 가능성 애노테이션이 없을 경우, 코틀린 컴파일러는 플랫폼 타입으로 인식한다.| Java | Kotlin |
|---|---|
@Nullable MyClass | MyClass? |
@NotNull MyClass | MyClass |
MyClass | MyClass? or MyClass |
?. , ?: , as? 안전한 연산을 위한 안전 연산자!! 안전하지 못한 참조를 위한 연산자 (Not Null Assertion)let 널 안정성 검증한 결과를 널이 될수 없는 타입을 받아들이는 함수에게 전달해주는 라이브러리 함수