프로그래밍백엔드 개발자

Kotlin에서 인라인 클래스(값 클래스)란 무엇이며, 어떤 용도로 사용되며, 적용할 때 어떤 제한이 있나요?

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

답변.

문제의 역사

Kotlin에서는 원시 타입 및 작은 구조체에 대한 래퍼를 사용할 때 런타임 오버헤드를 최소화하기 위해 인라인/값 클래스(현재는 값 클래스라고 합니다) 개념을 도입했습니다. 이러한 아이디어는 성능을 높이면서도 타입 안전성을 잃지 않기 위해 다른 언어(예: C# 구조체)에서 차용되었습니다.

문제

최적화 없이 래퍼 클래스를 생성하는 것은 메모리에 추가 객체를 생성하게 되어 성능, GC에 영향을 미치고 Boxing/Unboxing 오버헤드를 초래할 수 있습니다. 종종 UserId 대신 Int와 같은 엄격한 타입을 원하지만 실제로 객체를 생성하지는 않기를 원하게 됩니다.

솔루션

값 클래스는 value 수정자와 함께 선언됩니다. 대부분의 경우 JVM은 추가 객체를 생성하지 않으며, 값 클래스는 자신의 필드로 직접 대체됩니다(인라인). 이는 타입 안전성과 "그냥 Int"에 가까운 성능을 제공합니다.

코드 예:

@JvmInline 값 클래스 UserId(val value: Int) 재표시 id(id: UserId) = println(id.value) val id = UserId(15) 재표시(id) // 별도의 UserId 객체 생성 없이

주요 특징:

  • 클래스는 정확히 하나의 속성(val 또는 var)을 가져야 하며, 이 타입은 nullable일 수 없습니다.
  • 상속을 지원하지 않습니다(값 클래스는 상속받거나 상속할 수 없습니다).
  • 일부 제한 사항: init 블록을 가질 수 없고, lateinit 또는 초기화되지 않은 속성을 저장할 수 없으며, 모든 경우에 대해 리플렉션을 사용할 수 없습니다.

트릭 질문.

값 클래스는 여러 속성을 가질 수 있나요?

아니요, 값 클래스는 오직 하나의 속성만 가질 수 있습니다.

// 오류: // 값 클래스 Money(val amount: Int, val currency: String)

값 클래스에 nullable 속성을 생성할 수 있나요?

값 클래스의 값 필드는 nullable이 될 수 없습니다. 오직 non-nullable 타입만 가능해야 합니다.

// 오류: // 값 클래스 Name(val value: String?)

값 클래스에서 상속을 사용할 수 있나요?

값 클래스는 상속을 지원하지 않으며, 추상적이거나 sealed일 수 없습니다.

// 오류: // 값 클래스 NewId(val value: Int): BaseId()

일반적인 오류 및 안티 패턴

  • 여러 속성을 가진 복잡한 구조에 대해 값 클래스를 사용하려고 하는 시도
  • 값 클래스를 통해 nullable 값을 저장
  • 참조 메서드(예: equals/hashCode 메서드가 컴파일된 백엔드에서 예기치 않게 동작할 수 있음)를 사용하는 것

실제 예시

부정적인 케이스

개발자가 두 개의 속성을 가진 엔티티를 위해 값 클래스를 만들었다(예: Int와 String 쌍)고, 컴파일 오류가 발생했습니다.

장점:

  • 엄격한 타입을 달성하려고 시도 단점:
  • 작동하지 않음, 컴파일 불가

긍정적인 케이스

개발자가 하나의 필드를 가진 아이디 타입을 위해 값 클래스를 사용하였고, 이는 빠르고 안전하게 작동합니다.

장점:

  • 간결하고 안전한 코드
  • 런타임 오버헤드 없음 단점:
  • 오직 하나의 non-nullable 타입만 사용할 수 있음