본문 바로가기

Kotlin53

[Kotlin] Generics - in과 out 확실하게 알기 Generics의 in과 out은 코틀린이 타입 시스템을 더 안전하게 만들기 위한 장치다.그런데 in과 out 키워드는 처음 배울 때 확실하게 알기 어렵다(나만 그랬나?). 그래서 정리해본다.1. 시작하기에 앞서, Generics는 왜 쓸까?먼저 제네릭이 왜 필요한지 짚고 넘어가야한다. 제네릭은 타입을 마치 함수의 파라미터처럼 사용하는 기능이다. 이렇게 하면 다양한 타입에서 작동하면서도 타입 안정성을 보장하는 재사용 가능한 코드를 만들 수 있다.예를 들어, List은 문자열만 담는 리스트, List는 정수만 담는 리스트가 된다.List라는 하나의 틀을 만들어 놓고, 필요할 때마다 T 자리에 원하는 타입을 넣어 쓰는 것이다. 이렇게 하면 잘못된 타입이 들어가는 걸 컴파일 시점에 미리 막을 수 있어 안전하다.. 2025. 4. 16.
[Kotlin] reified 키워드 reified 키워드는 코틀린에서 인라인 함수의 타입 파라미터에 붙여서, 해당 타입 정보를 런타임에도 유지하도록 하는 키워드다. 기본적으로 코틀린의 제네릭은 타입 소거(type erasure) 때문에 런타임에 구체적인 타입 정보를 알 수 없지만, reified를 사용하면 인라인 함수 내부에서 타입 파라미터를 실제 타입처럼 사용할 수 있게 된다. 예를 들어, 일반 함수에서는 아래와 같이 제네릭 타입 파라미터를 사용할 때, 타입 정보를 알 수 없으므로 is 연산자나 ::class 등을 사용할 수 없다.// 일반적인 제네릭 함수 (타입 소거 때문에 T의 구체적 타입을 알 수 없음)fun isInstance(value: Any): Boolean { // 컴파일 에러: 'T'의 구체적인 타입 정보를 알 수.. 2025. 4. 3.
[Kotlin in Action] 10.2 리플렉션: 실행 시점에 코틀린 객체 내부 관찰 코틀린에서 리플렉션을 사용하려면 두 가지 서로 다른 리플렉션 API를 다뤄야 한다.첫 번째는 자바가 java.lang.reflect 패키지를 통해 제공하는 표준 리플렉션이다. 코틀린 클래스는 일반 자바 바이트코드로 컴파일되므로 자바 리플렉션 API도 코틀린 클래스를 컴파일한 바이트코드를 완벽히 지원한다.두 번째 코틀린이 kotlin.reflect 패키지를 통해 제공하는 코틀린 리플렉션 API다. 이 API는 자바에는 없는 프로퍼티나 null이 될 수 있는 타입과 같은 코틀린 고유 개념에 대한 리플렉션을 제공한다. 하지만 현재 코틀린 리플렉션 API는 자바 리플렉션 API를 완전히 대체할 수 있는 복잡한 기능을 제공하지는 않는다. 따라서 나중에 보겠지만 자바 리플렉션을 대안으로 사용해야 하는 경우가 생긴다.. 2025. 4. 3.
[Kotlin in Action] 10.1 annotation 선언과 적용 10.1.1 annotation 적용자바와 코틀린에서 @Deprecated annotation의 의미는 똑같다. 하지만 코틀린에서는 replaceWith 파라미터를 통해 옛 버전을 대신할 수 있는 패턴을 제시할 수 있고, API 사용자는 그 패턴을 보고 지원이 종료 될 API 기능을 더 쉽게 새 버전으로 포팅할 수 있다. 다음 예제는 @Deprecated annotation에 어떻게 인자를 지정하는지에 대한 코드다.// 사용 금지를 설명하는 메시지와 대체할 패턴을 지정@Deprecated("Use removeAt(index) instead.", ReplaceWith("removet(index)"))fun remove(index: Int) { ... }annotation에 인자를 넘길 때는 일반 함수와 마.. 2025. 4. 3.
[Kotlin] 스타 프로젝션(*)과 Any의 차이 스타 프로젝션(List) 예제fun printList(list: MutableList) { // 리스트의 요소를 안전하게 읽을 수 있다. 하지만 쓰기는 불가능하다. (반환 타입은 Any?로 추론) for (item in list) { println(item) }}fun main() { val stringList: MutableList = mutableListOf("A", "B", "C") printList(stringList) val intList: MutableList = mutableListOf(1, 2, 3) printList(intList)}MutableList는 "모든 타입의 리스트"를 받겠다는 의미지만, 구체적인 타입 정보가 없으므로 읽.. 2025. 4. 3.