Null Safe
var str : String = "Hello World"
str = null
//error
var str_1: String? = "Hello World"
str_1 = null
//Nullablevar nullable: String? = "Kotlin"
fun nullSafe(str: String?): String? {
return str
}Last updated
var str : String = "Hello World"
str = null
//error
var str_1: String? = "Hello World"
str_1 = null
//Nullablevar nullable: String? = "Kotlin"
fun nullSafe(str: String?): String? {
return str
}Last updated
var str: String? = "Hello World!"
str.length
//error
str?.length
//correct
// bar가 null이 아닐 경우에만 해당 값을 대입, 그렇지 않은 경우 null을 foo에 대입한다.
val foo = bar?.baz
//foo가 null이 아닐 경우에만 bar() 호출
foo?.bar()
//java
public class Contact {
@NotNull
String name;
@Nullable
Address address;
}
class Address {
@NotNull
String line1;
@Nullable
String line2;
}
// Address.line1은 null값을 허용하지 않지만,
// address가 null인 경우 null을 반환하게 되므로 값 line의 타입은 null값을 허용해야 한다.
val line: String? = Contact().address?.line1
// 주소가 없거나 line2가 없을 경우 기본값인 "No Address"를 리턴
val line: String = Contact().address?.line2 ?: "No Address"
str!!.length
// 절대 Null이 없을경우에 강제호출하는 방법
// 주의해야될점이 Nullable로 선언한 변수에 !!로 접근을 하면 컴파일에는 문제가 없을것이다.
// 하지만 런타임에서 이 Nullable한 값에다가 Null이 들어가는데 Null이 아니라고 !!로 접근을 하면
// 런타임중에 NPE 뿜는다.
// 고로 !!는 내가 굳이 Null이 절대 오지 않을것이다 라고 보장할 수 있는 부분에만 사용을 해야한다.
val foo: Foo? = nullable...
// 값 foo는 null값을 포함하지 않음을 보증.
val nonNullFoo: Foo = foo!!
// 값 foo가 null값이 아님을 보증하면서 bar()함수 호출
foo!!.bar()
// 값 foo가 null이 아님을 보증하면서 baz 프로퍼티 접근
foo!!.bazvar str: String? = "Hello World!"
str?.length ?: -1
// 앞에 값이 Null이 아니라면 그냥 Nullable의 length 값을 가져오고,
// Null이라면 Default로 설정해둔 값을 가져온다. (?: 의 뒤의 값.)
// 이런식으로 널처리를 쉽게 할 수 있다.
fun generateMapWithAddress(address: String) : Image? {
// 검색결과가 없을경우 Exception 발생
val postal = findPostalCode(address) ?: throw IllegalStateException()
}val foo: String = "foo"
//java.lang.ClassCastException 발생
val bar: Int = foo as Int
//자바에서는 지원되지 않는 자료형으로 변환을 시도할 가능성이 있는 부분을
//try-catch 블록으로 감싸 처리해야 하지만,
//코틀린에선 as? (안전한변환) 연산자를 사용하여 이 문제를 간편하게 해결할 수 있다.
//as? 연산자는 형변환이 실패할 경우 예외를 발생시키는 대신에 null값을 반환한다.
//따라서 변환되는 값을 통해 변환결과를 바로 확인할 수 있다.
//null값이 올 수 있으므로 받는쪽의 자료형을 Nullable로 해주어야 한다.
val foo: String = "foo"
//bar가 null을 허용하도록 Int?로 정의한다.
//형변환에 실패하므로 bar에는 null이 할당된다.
val bar: Int? = foo as? Int
//실패의 경우 null을 반환하기 때문에 엘비스 연산자와 함께 사용할 수 있다.
val bar: Int = foo as? Int ?: 0 //형변환 실패의 경우 기본값을 0으로 지정.//java
class Person {
String name;
public String getName() {
return name;
}
}//kotlin
val person: Person = ...
// n1은 null값을 허용하지 않는다.
val n1: String = person.name
// n2는 null값을 허용한다.
val n2: String? = person.name
// 이런 특징 때문에 플랫폼타입 객체를 사용할 때는 항상 객체의 null값 여부를 확인해야만 한다. -> NPE
// 코틀린에서는 이를 해결하기 위해 자바의 annotation을 인식해 객체의 null 허용여부를 판단한다.//java
class Person {
@Nullable
String name; //이런 식으로 어노테이션을 붙여주면 name필드는 코틀린에서 nullable한 프로퍼티(String?)으로 인식된다.
public String getName() {
return name;
}
}//kotlin
//실패
val n1: String = person.name
//성공
val n2: String? = person.name