0Pricing
Kotlin Academy · Pelajaran

Proyeksi Bintang dan Kapan Menggunakan *

Terapkan proyeksi bintang untuk tipe generik yang tidak diketahui dan pahami keterbatasannya.

Proyeksi Bintang dan Kapan Menggunakan * adalah pelajaran Kotlin Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Kotlin Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Kotlin Academy mencakup 4 pelajaran total.

Apa Itu Proyeksi Bintang

Proyeksi bintang (*) adalah cara Kotlin untuk menyatakan "tipe generik dengan argumen tipe yang tidak diketahui." Ini merupakan padanan aman dari tipe mentah Java atau wildcard tanpa batas <?>.

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"))
}

Membaca dari Tipe yang Diproyeksikan dengan Bintang

Dari List<*>, Anda dapat membaca elemen sebagai Any?. Anda tidak dapat menambahkan elemen karena tipe sebenarnya tidak diketahui.

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))
}

Bintang vs out Any

List<*> dan List<out Any?> setara. Proyeksi bintang merupakan singkatan dari proyeksi kovarian dengan batas atas.

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
}

Bintang pada Parameter Fungsi

Gunakan * dalam tanda tangan fungsi saat Anda perlu menerima varian generik apa pun, tetapi hanya memanggil metode yang tidak memerlukan pengetahuan tentang 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))
}

Bintang dengan MutableList

Untuk MutableList<*>, Anda dapat membaca sebagai Any?, tetapi sama sekali tidak dapat menulis—kompilator mencegahnya.

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]
}

Kelas dengan Proyeksi Bintang

Saat memeriksa tipe kelas generik saat runtime, gunakan proyeksi bintang karena argumen tipe telah dihapus.

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
}

Beberapa Parameter Bintang

Sebuah fungsi dapat memiliki beberapa parameter yang diproyeksikan dengan bintang saat bekerja dengan pasangan atau peta yang tipenya tidak diketahui.

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))
}

Kapan NOT Sebaiknya Digunakan

Hindari proyeksi bintang saat Anda perlu menulis ke koleksi atau saat dapat menggunakan parameter tipe berbatas—parameter berbatas memberikan lebih banyak informasi.

// 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)
}

Bintang dengan Pemeriksaan Tipe dan Casting

Gunakan proyeksi bintang untuk melakukan pemeriksaan instanceof pada kelas generik, lalu lakukan casting ke tipe tertentu untuk pekerjaan sebenarnya.

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)
}

Praktik: Pengirim Peristiwa Generik

Pengirim yang menerima Handler<*> apa pun, tetapi mengirimkan peristiwa bertipe dengan aman.

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)
}

Bintang dalam Konteks reified

Proyeksi bintang sangat umum dalam kode refleksi dan serialisasi, saat tipe runtime diperiksa melalui KClass<*>.

fun printClassName(klass: kotlin.reflect.KClass<*>) {
    println(klass.simpleName)
}
fun main() {
    printClassName(String::class)     // String
    printClassName(List::class)       // List
    printClassName(Int::class)        // Int
}

Pemeriksaan Singkat

Tipe apa yang Anda dapatkan saat membaca dari List<*>?

Rekapitulasi

Proyeksi bintang (*) menerima varian generik apa pun untuk akses hanya-baca. Gunakan proyeksi ini untuk pemeriksaan tipe, utilitas generik, dan refleksi. Hindari penggunaannya saat Anda perlu menulis ke koleksi atau saat parameter tipe berbatas memberikan keamanan tipe yang lebih baik.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Proyeksi Bintang dan Kapan Menggunakan *” gratis?

Ya — teks lengkap “Proyeksi Bintang dan Kapan Menggunakan *” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Kotlin Academy, upgrade ke CoddyKit PRO. Kursus Kotlin Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Proyeksi Bintang dan Kapan Menggunakan *”?

Terapkan proyeksi bintang untuk tipe generik yang tidak diketahui dan pahami keterbatasannya. Kamu berlatih Kotlin Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Kotlin Academy?

Tidak diperlukan pengalaman sebelumnya. Kotlin Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Proyeksi Bintang dan Kapan Menggunakan *” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Kotlin Academy ini?

Ya. Setiap pelajaran Kotlin Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Fungsi Generik dan Batasan Tipe dengan where
  2. Variansi di Lokasi Deklarasi: in dan out
  3. Proyeksi Bintang dan Kapan Menggunakan *
  4. Penghapusan Tipe dan Parameter Tipe reified
← Kembali ke Kotlin Academy