티스토리 뷰

Server

Kotlin의 Any와 Nullable (1)

니용 2020. 6. 29. 12:01
반응형

Author: 니용

 


String은 Java에서 사용한 Wrapper Type 중 대표적인 객체지향 프로그래밍의 시초를 알린 클래스 중 하나입니다. 이전에 야만 해도 하드웨어적인 한계가 있고, 주어진 용량을 알차게 사용하였기 때문에 String보다는 char 배열을 더 사용하였거나 숫자형 타입(int, long 등)을 더 사용했었다면 지금처럼 많이 발전된 상태에서 String이 많이 사용되고 있습니다. 

 

이번에는 Kotlin 언어의 Null 처리와 향상된 점을 같이 살펴보려 합니다.

 

Java Wrapper Type의 문제점

Java의 클래스 중에도 Integer, Long과 같은 Wrapper Type Class가 존재합니다. 문제는 이를 활용할 때 발생하게 되는데 다음과 같은 상황에서 확인해보겠습니다.

Long longValue = null;
int integerVal = longValue.intValue();

위와 같은 상황이 이루어지면 null.intValue()의 메서드는 지원하지 않기 때문에 Runtime에서 NPE(Null Pointer Exception)이 출력될 것입니다. 가령 try catch 문으로 NPE를 잡아주어도 longValue를 아래에서 또 사용하는 상황이 온다면 똑같은 문제가 발생할 것입니다. Kotlin에서는 이와 같은 문제를 잡기 위해?를 사용합니다.

 

 

Any Type 그리고 ?

Any는 Kotlin에서 사용하는 Object입니다. 

모든 변수에 대한 Null을 잡기 위해 '?' 한 문자로 대체되었습니다. 예시는 이렇습니다.

val nullableVal: Any? = null
val npeVal: Any

그래서 이것을 사용하기 위한 방법도 조금씩 달라집니다.

print(nullableVal?.toString())
print(npeVal.toString())

nullableVal의 경우는 ?. 연산자를 사용하여 NPE를 방지하였습니다. 

npeVal은 기존과 같이 . 연산자를 사용하여 체이닝을 진행하였네요.

 

'?.' 이 친구를 통상 Null Safe Operator라고 부릅니다.

'?.' 연산자를 사용하는 것은 Compile 단계에서 NPE를 잡아주기 위함입니다.

이 친구는 코드로 풀면 이렇게 되겠죠

if(nullableVal != null) nullableVal.toString() else null

다른 클래스의 Property에 접근 시에도 자주 사용되기에 이처럼 사용할 수 있을 것입니다.

 

val location = nation?.city?.address?.building?.location
// 특정 위치는 특정 국가 -> 도시 -> 주소 -> 건물을 묘사했어요

 

Elvis Operator

이전에 Optional Class에 대해 다루어 본 적이 있습니다.

간단히 말하면 변수에 nullable value가 들어왔을 때 기본값을 지정해주는 것인데요, Kotlin에서는 이를 Elvis Operator(엘비스 연산자)라고 합니다.

 

(생긴 모양이 엘비스 프레슬리를 닮아서 명명이 되었다고 하네요..ㅎㅎ 커엽,,,)

 

사용법은 '?:'를 사용하면 됩니다.

 

fun getNickname(nickname: String?): String {
   val res = nickname ?: "unknown"
   return res
}

// 이는 if (nickname == null) "unknown" else nickname 와 같아요

 

Safe Cast

 

클래스의 타입을 체크하기 위한 is 키워드가 있었는데요, as 키워드를 사용하면 type을 변환할 수 있습니다.

as를 사용할 때 주의점은 타입이 맞지 않으면 ClassCastException이 발생합니다. 그래서 Kotlin은 이를 방지하기 위한 도구로 as? 를 사용합니다

 

class Abbo(val id: String) {
   override fun equals(o: Any?): Boolean {
      val other = o as? Abbo ?: return false
      return other.id == id
   }
}

위 소스를 Java 소스로 본다면 아래와 같겠죠.

Abbo o = null;
if (o instanceof Abbo) {
   o = (Abbo)o;
}
else {
   return false;
}

 

Not null 처리

 

Java에서는 Kotlin처럼 하드 하게 런타임 체크를 하지 않기 때문에 계속 null처리를 해주면서 코딩을 해야 하는 불편함이 있습니다. Kotlin에서 이를 해결하기 위해 nullable 설정된 property를 강제로 not null로 바꿔주는 연산자가 있습니다.

 

바로 !! 입니다. 느낌표 두 개만으로 처리가 가능한데, 쉬운 이해를 위해 예시를 들겠습니다.

 

fun split(str: String?) {
   val strNotNull: String = str!!
   print(strNotNull.length)
   return strNotNull.split(" ")
}

이렇게 되면 Line Number 3부터 strNotNull의 변수는 not null이기 때문에 컴파일러에서 값이 무조건 있는 것으로 체크가 됩니다. 문제는 이렇게 사용하였을 때 split(null)이 선언되었다면 NPE가 발생할 것입니다. 사실 이와 같이 사용하는 경우는 드물지만 예시를 위해 지정하였습니다.

 

이 방법도 똑같이 property로 사용 가능합니다. 하지만 이렇게 사용하였을 때 NPE가 어디서 발생하였는지 알 수 없기에 추천하는 방법이 아닙니다. 

nation!!.city!!.address!!.building!!.location
// 특정 위치는 특정 국가 -> 도시 -> 주소 -> 건물을 묘사했어요

 

반응형

'Server' 카테고리의 다른 글

MongoDB 설치하기  (0) 2020.06.30
Kotlin의 lateinit과 Nullable (2)  (0) 2020.06.30
Kotlin의 생성자와 data class  (0) 2020.06.29
Kotlin의 Control Flow  (0) 2020.06.26
Kotlin의 함수(Function)  (0) 2020.06.26
[Spring] @Bean과 @Component의 차이  (0) 2020.06.25
댓글
공지사항