Kotlin Academy · Lesson

Use-Site Variance

Type projections.

Lesson 3 of 413 steps

Use-Site Variance is a free Kotlin Academy lesson on CoddyKit. This is lesson 3 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Kotlin Academy learning path, and your progress syncs across the web and the CoddyKit app. The Kotlin Academy course includes 4 lessons in total.

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.

Free to start

Learn Kotlin with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
51
Lessons
203

Frequently Asked Questions

Is the “Use-Site Variance” lesson free?

Yes — any 3 lessons of the Kotlin Academy learning path, including “Use-Site Variance”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Kotlin Academy course includes 4 lessons in total.

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, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.

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