코틀린은 향상된 null체크, 스마트 타입 캐스팅, 유연한 타입 체킹을 이용해서 개발자들의 코드를 더욱 타입 안정적이면서도 적은 오류를 만들도록 최선을 다한다. NullPointerException 같은 경우에도 컴파일 시간에 최대한 빠르게 방지할 수 있도록 도와준다.
이번 장에서 다룰 내용은 Any와 Nothing 클래스, null 기능 참조와 관련된 연산자, 스마트 캐스트의 장점 등으로, 오류를 줄이고 코드의 유지보수를 쉽게 하도록 디자인하는 데 도움이 될 것이라고 한다. 👻
코틀린의 Any 클래스는 자바의 Object에 대응되는 클래스라고 볼 수 있다.
Nothing 클래스는 함수가 아무것도 리턴하지 않을 경우 리턴하는 클래스이다. -> method가 하나 이상의 브랜치에서 아무것도 리턴하지 않을 경우 타입 체크를 한다면 Nothing 클래스가 있어야 유용하다.
fun computeSqrt(n: Double): Double {
if(n >= 0) {
return Math.sqrt(n)
} else {
throw RuntimeException("No negative please")
}
}
if문 - Double 리턴, else문 - 예외처리 (Nothing 타입)
Nothing class는 블로그 글을 참고하며 이해해봤지만 아직 조금 애매한 것 같다. 이후 Unit과 비교해서 더 자세히 찾아보고 추가해야 할 듯 하다. 🤧
Java에서는 참조가 리턴되어야 할 메소드에서 null을 리턴할 때의 오류를 염려해도 해당 코드를 짜는 것을 막을 수 없다. 프로그래머는 Optional를 사용하는 방법을 선택해야 하지만 언제, 어디서 사용하는지 매우 혼란스럽다.
코틀린은 null을 null 불가 참조에 할당하거나 참조 타입이 null 불가인 곳에 리턴하려고 하면 컴파일 오류가 난다.(만약 자바라면 컴파일이 아닌, 실행 시간에서 오류가 날 것이다.)
null 불가 타입들은 각자 대응하는 null 가능타입이 있다.
ex>
null 불가 : String -> null 가능 : String?
null이 될 수 있는 객체에 접근하기 전에 먼저 null 체크를 해줘야 한다.
if (name != null){
return name.reversed()
}
return null
null 체크가 너무 지저분하다. 이제 안정성은 유지하며 지저분한 코드를 제거하자 👍
return name?.reversed()
로 간단하게 바꿀 수 있다!
val result = name?.reversed()?.toUpperCase()
return if (result == null) "Joker" else result
⬇️
return name?.reversed()?.toUpperCase() ?: "Joker" //엘비스 연산자 사용
not-null 확정 연산자 !!는 그냥 사용하지 마라.
가끔 지금 가지고 있는 객체가 내가 예상한 특정 객체인지 궁금할 때가 있다. 그러면 해당 객체가 맞는지 검증을 하고, 특정 타입으로 캐스팅을 하면 원하는 메소드를 사용할 수 있다고 한다.
실행 시간 타입 체크에 대해선 논란이 많지만, 아주 유용하며, equals()메소드와 when을 사용할 때는 반드시 필요하다.
class Animal {
Override operator fun euqals(other: Any?) = other is Animal
}
위 코드에서는 other이 Animal 클래스인지 확인한다. 예상된 타입이라면 true, 아니라면 false 리턴
override operator fun equals(other: Any?): Boolean {
return if (other is Animal) age == other.age else false
}
⬇️override operator fun equals (other: Any?) =
other is Animal && age = other.age