프로그래밍백엔드 개발자

코 틀린의 스마트 캐스팅이란 무엇인가요? 조건, when 표현식, 널 가능 유형, 사용자 정의 getter 및 속성에서 어떻게 작동합니까? 예시와 잠재적인 함정을 제시하세요.

Hintsage AI 어시스턴트로 면접 통과

답변.

스마트 캐스팅은 코틀린 컴파일러가 특정 유형이나 널을 검사한 후 타입을 "다운캐스팅"하는 메커니즘입니다. 이를 통해 명시적 변환 없이 캐스팅된 타입의 속성과 메서드를 사용할 수 있습니다.

예:

fun demo(x: Any) { if (x is String) { println(x.length) // x는 자동으로 String으로 변환됨 } }

작동하는 경우:

  • is / !is 연산자 (예: if 또는 when에서)
  • 널 가능 변수 (if (x != null))
  • when 표현식

작동하지 않는 경우:

  • 속성이 사용자 정의 getter를 가질 때 (컴파일러는 검사와 사용 사이에 값이 변경되었을 가능성을 잃음)
  • 클래스의 open/var 속성에 대해

널 가능 예:

val str: String? = getString() if (str != null) println(str.length) // 스마트 캐스트

작동하지 않는 경우:

val something: Any get() = fetch() if (something is String) { println(something.length) // 오류: 스마트 캐스팅이 불가능 }

문제점이 있는 질문.

메서드 내부의 클래스 open 또는 var 속성에 대해 스마트 캐스팅을 신뢰할 수 있나요?

아니요! 스마트 캐스팅은 로컬 변수와 final 클래스의 val 속성에서만 작동합니다. open 또는 var 속성의 경우, 컴파일러는 다른 스레드나 하위 클래스에서 값이 변경될 수 있는지 확신하지 못합니다. 이 경우 수동 캐스트 또는 로컬 변수가 필요합니다.

open class Base { open var maybeString: Any? = "abc" fun check() { if (maybeString is String) { // println(maybeString.length) // 오류: 스마트 캐스팅이 불가능 val asString = maybeString as String println(asString.length) // 명시적 캐스트 } } }

주제의 미세한 차이점으로 인한 실제 오류 예시.


이야기

한 프로젝트에서 화면 논리를 위해 open var 데이터 모델 속성을 사용했습니다. 프로그래머는 if (model is SomeType) 검사를 한 후 스마트 캐스트에 의존했으나, 컴파일 시 모든 타입을 수동으로 변환해야 했고, 이는 가독성을 저하시켰으며 스마트 캐스트의 var/open 제한을 몰라서 코드 중복도 발생했습니다.


이야기

getter를 통해 데이터 수신 (예: 델리게이트 또는 유효성 검사)을 할 때, 값에 대한 스마트 캐스트가 작동하지 않았습니다. 개발자는 그 이유를 이해하지 못해 몇 시간 동안 디버깅에 시간을 허비하다가, 컴파일러가 이러한 getter에 대해 스마트 캐스트를 적용하지 않는 이유가 호출 사이에 다른 값이 반환될 수 있기 때문이라는 것을 발견했습니다.


이야기

프로젝트에서 널 가능 값 처리 시 if (obj != null) 스마트 캐스트가 분기 내에서 작동했지만, 코드 병렬 처리 시 보장 영역 외부에서 접근으로 인해 NullPointerException이 발생했습니다. 이는 스마트 캐스트의 로컬 동작과 널 가능 변수에 대한 다중 스레드 시나리오의 특징에 대한 이해가 부족함을 드러냈습니다.