스타 프로젝션과 *를 사용할 때
알 수 없는 제네릭 타입에 스타 프로젝션을 적용하고 그 한계를 이해해 보세요.
스타 프로젝션과 *를 사용할 때은(는) CoddyKit의 무료 Kotlin Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Kotlin Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Kotlin Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
스타 프로젝션이란 무엇입니까
스타 프로젝션(*)은 "타입 인수를 알 수 없는 제네릭 타입"을 나타내는 Kotlin의 방식입니다. Java의 원시 타입이나 제한되지 않은 와일드카드 <?>에 대응하는 안전한 방식입니다.
fun printList(list: List<*>) {
for (item in list) println(item)
}
fun main() {
printList(listOf(1, 2, 3))
printList(listOf("a", "b"))
printList(listOf(true, 42, "mixed"))
}스타 프로젝션 타입에서 읽기
List<*>에서는 요소를 Any?로 읽을 수 있습니다. 실제 타입을 알 수 없으므로 요소를 추가할 수 없습니다.
fun process(list: List<*>) {
val first: Any? = list.firstOrNull()
println("First: $first, Size: ${list.size}")
// list.add("x") // compile error: can't write to List<*>
}
fun main() {
process(listOf(10, 20, 30))
}스타 프로젝션과 out Any
List<*>와 List<out Any?>는 동등합니다. 스타 프로젝션은 상한을 사용한 공변 프로젝션의 축약형입니다.
fun sumStars(list: List<*>): Int = list.size
fun sumOut(list: List<out Any?>): Int = list.size
fun main() {
val l = listOf(1, "two", true)
println(sumStars(l)) // 3
println(sumOut(l)) // 3
}함수 매개변수의 스타 프로젝션
모든 제네릭 변형을 받아들이되 T를 알아야 하는 메서드는 호출할 필요가 없을 때 함수 시그니처에 *를 사용합니다.
fun containerInfo(map: Map<*, *>): String {
return "keys=${map.keys.size}, values=${map.values.size}"
}
fun main() {
val m = mapOf(1 to "one", 2 to "two")
println(containerInfo(m))
}MutableList에서의 스타 프로젝션
MutableList<*>에서는 Any?로 읽을 수 있지만 전혀 쓸 수 없습니다. 컴파일러가 이를 방지합니다.
fun clearFirstElement(list: MutableList<*>) {
if (list.isNotEmpty()) {
list.removeAt(0) // OK: remove by index doesn't need T
// list.add("x") // Error: can't write unknown type
}
}
fun main() {
val m = mutableListOf(1, 2, 3)
clearFirstElement(m)
println(m) // [2, 3]
}스타 프로젝션을 사용하는 클래스
런타임에 제네릭 클래스 타입을 검사할 때는 타입 인수가 소거되므로 스타 프로젝션을 사용합니다.
fun isListOfSomething(obj: Any): Boolean {
return obj is List<*> // OK with star
// obj is List<String> // Warning: cannot check erased type
}
fun main() {
println(isListOfSomething(listOf(1, 2))) // true
println(isListOfSomething("not a list")) // false
}여러 스타 매개변수
알 수 없는 타입의 쌍이나 맵을 다룰 때 함수에 여러 스타 프로젝션 매개변수를 사용할 수 있습니다.
fun describeMap(map: Map<*, *>) {
map.forEach { (k, v) ->
println("${k?.javaClass?.simpleName} -> ${v?.javaClass?.simpleName}")
}
}
fun main() {
describeMap(mapOf("key" to 42, 1 to true))
}스타 프로젝션을 사용하지 않을 때
컬렉션에 써야 하거나 제한된 타입 매개변수를 사용할 수 있다면 스타 프로젝션을 피합니다. 제한된 타입 매개변수가 더 많은 정보를 제공하기 때문입니다.
// Bad: loses type information
fun addToStar(list: MutableList<*>, item: Any?) {
// list.add(item) // compile error
}
// Better: use bounded type parameter
fun <T : Any> addTyped(list: MutableList<T>, item: T) {
list.add(item)
}
fun main() {
val l = mutableListOf("a")
addTyped(l, "b")
println(l)
}타입 검사와 캐스트에서의 스타 프로젝션
스타 프로젝션을 사용해 제네릭 클래스의 instanceof 검사를 수행한 다음, 실제 작업을 위해 특정 타입으로 캐스트합니다.
fun handleResponse(response: Any) {
if (response is List<*>) {
val list = response as List<*>
println("List with ${list.size} elements")
val first = list.firstOrNull()
if (first is String) println("First string: $first")
}
}
fun main() {
handleResponse(listOf("hello", "world"))
handleResponse(42)
}실습: 제네릭 이벤트 디스패처
모든 Handler<*>를 받아들이면서 타입이 지정된 이벤트를 안전하게 전달하는 디스패처입니다.
interface Handler<in T> { fun handle(event: T) }
class LogHandler : Handler<Any> {
override fun handle(event: Any) = println("Event: $event")
}
fun dispatch(handler: Handler<*>, event: Any) {
@Suppress("UNCHECKED_CAST")
(handler as Handler<Any>).handle(event)
}
fun main() {
dispatch(LogHandler(), "click")
dispatch(LogHandler(), 42)
}reified 문맥에서의 스타 프로젝션
스타 프로젝션은 KClass<*>를 통해 런타임 타입을 검사하는 리플렉션 및 직렬화 코드에서 특히 자주 사용됩니다.
fun printClassName(klass: kotlin.reflect.KClass<*>) {
println(klass.simpleName)
}
fun main() {
printClassName(String::class) // String
printClassName(List::class) // List
printClassName(Int::class) // Int
}빠른 확인
List<*>에서 읽을 때 어떤 타입을 얻게 됩니까?
복습
스타 프로젝션(*)은 읽기 전용 접근을 위해 모든 제네릭 변형을 받아들입니다. 타입 검사, 제네릭 유틸리티, 리플렉션에 사용합니다. 컬렉션에 써야 하거나 제한된 타입 매개변수가 더 나은 타입 안전성을 제공할 때는 사용하지 않습니다.
자주 묻는 질문
“스타 프로젝션과 *를 사용할 때” 강의는 무료인가요?
네 — “스타 프로젝션과 *를 사용할 때” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Kotlin Academy 강의 전체를 잠금 해제할 수 있습니다. Kotlin Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“스타 프로젝션과 *를 사용할 때”에서 뭘 배우나요?
알 수 없는 제네릭 타입에 스타 프로젝션을 적용하고 그 한계를 이해해 보세요. 브라우저에서 직접 실행하는 실습 코드로 Kotlin Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Kotlin Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Kotlin Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“스타 프로젝션과 *를 사용할 때” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Kotlin Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Kotlin Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- where를 사용한 제네릭 함수와 타입 제약
- 선언 위치 변성: in과 out
- 스타 프로젝션과 *를 사용할 때
- 타입 소거와 reified 타입 매개변수