0Pricing
Kotlin Academy · Lesson

Use-Site Variance

Type projections.

Use-Site Variance is a free Kotlin Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Kotlin Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Use-Site Variance

Sometimes a generic class is invariant overall, but a specific function only produces or only consumes the type. Use-site variance (type projections) applies out or in right at the place a type is used.

Why Use-Site Variance

An invariant class like MutableList<T> cannot be made covariant at declaration because it both reads and writes T. But a particular function might only read from it, and projections let us express that safely.

out Projection

Writing Array<out T> as a parameter type produces a covariant view: you can read T but not write it. This lets you pass an Array<String> where Array<out Any> is expected.

fun printArray(items: Array<out Any>) {
    for (item in items) println(item)
}

fun main() {
    val names: Array<String> = arrayOf("Ann", "Bob")
    printArray(names)
}

Reading Only

With an out projection, the compiler allows reads (output) but forbids writes (input), because writing could violate type safety for the original array.

in Projection

Writing Array<in T> produces a contravariant view: you can write T into it but reads come back as Any?. This lets you accept arrays of T or any supertype.

fun fill(dest: Array<in Int>, value: Int) {
    for (i in dest.indices) dest[i] = value
}

fun main() {
    val numbers: Array<Number> = arrayOf(0, 0, 0)
    fill(numbers, 7)
    println(numbers.toList())
}

Writing Only

With an in projection you may write values of T (input) but the element type is seen as the top type for reads, since the actual element type could be any supertype.

Projections vs Declaration-Site

Declaration-site variance (class Box<out T>) applies everywhere the class is used. Use-site projections (Box<out T> as a parameter) apply only at that one spot. Use projections when the class itself must stay invariant.

The Star Projection

When you do not care about the type argument at all, use the star projection *. List<*> means a list of some unknown type; you can read elements as the upper bound and cannot safely write.

fun printSize(collection: List<*>) {
    println("Size: ${collection.size}")
}

fun main() {
    printSize(listOf(1, 2, 3))
    printSize(listOf("a", "b"))
}

Star Projection Limits

With * you can still call type-independent members (like size) and read elements as Any?, but you cannot add elements because the real type is unknown.

fun main() {
    val unknown: List<*> = listOf("x", "y")
    val first: Any? = unknown.first()
    println(first)
}

Choosing a Projection

Use out T when a function only reads, in T when it only writes, and * when the exact type is irrelevant. These projections keep invariant classes usable in flexible, type-safe ways.

Relation to Java Wildcards

Kotlin's out T and in T projections map to Java's ? extends T and ? super T wildcards. If you know Java generics, projections will feel familiar.

Quick Check

What can you do with a parameter typed as Array<out Any>?

Recap

Use-site variance applies out (read-only) or in (write-only) projections at a specific usage, and * as a star projection when the type is unknown. This makes invariant classes flexible without changing their declaration. Next you will restrict type parameters with generic constraints.

Frequently asked questions

Is the “Use-Site Variance” lesson free?

Yes — the full text of “Use-Site Variance” is free to read here on the web, and the Kotlin Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Kotlin Academy course, upgrade to CoddyKit PRO.

What will I learn in “Use-Site Variance”?

Type projections. You practise Kotlin Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Kotlin Academy?

No prior experience is required. Kotlin Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Use-Site Variance” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Kotlin Academy lesson?

Yes. Every Kotlin Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Generic Functions and Classes
  2. Declaration-Site Variance
  3. Use-Site Variance
  4. Generic Constraints
← Back to Kotlin Academy