Explain Kotlin's declaration-site variance with in and out

This tests your grasp of generic type safety and API design. Explain that out marks covariant producers (e.g., List<out E>) and in marks contravariant consumers, then contrast this cleaner declaration-site model with Java's repetitive use-site wildcards.
What's really being asked
This question tests your deep understanding of generic type systems, specifically the trade-offs between Kotlin's declaration-site variance and Java's use-site variance (wildcards). The interviewer wants to see if you can move beyond simple definitions and explain why this feature exists: to create safer, more flexible, and cleaner generic APIs by embedding variance rules directly into the type's definition.
The full answer
A strong answer connects the keywords to their roles and contrasts them with Java. First, define covariance: out makes a type a producer, allowing subtypes to be used (a Source<String> is a Source<Any>). Second, define contravariance: in makes a type a consumer, allowing supertypes to be used (a Comparator<Any> is a Comparator<String>). Third, explain this is "declaration-site" variance because it's part of the class/interface declaration, like List<out E>. Fourth, contrast this with Java's "use-site" variance, where callers must repeatedly use wildcards like List<? extends Object>, making Kotlin APIs simpler for consumers.
The mistakes people make
The most common red flag is confusing in and out. A candidate who says out is for consumers immediately signals a shallow understanding. Another mistake is conflating variance with immutability; a covariant collection (List<out T>) is not necessarily immutable, you can still call methods like clear() that don't involve the generic type T. Finally, senior candidates are expected to provide the "why"—failing to contrast declaration-site with use-site variance and explain the benefit to the API consumer is a missed opportunity to show depth.
What usually comes next
Be ready for: "When is a generic type invariant, and why is that the default?" (When it's both a producer and consumer of T, like MutableList<T>). "What is type projection and when is it needed?" (It's Kotlin's equivalent of a use-site wildcard, used to handle types that aren't declared as covariant/contravariant, e.g., passing a MutableList<String> to a function expecting MutableList<out Any>).
A concrete example
Kotlin's List<out E> interface is covariant. Because it's a producer (you only get elements out of it via get()), the compiler allows you to assign a List<Int> to a variable of type List<Number>. Conversely, the Comparator<in T> interface is contravariant. It's a consumer (it only consumes T for comparison), so you can assign a Comparator<Number> to a variable of type Comparator<Int>, because a comparator that can handle any number can certainly handle an integer.
Interview question
To maximize type flexibility for a generic interface DataSink<T> that exclusively consumes elements of type T, which variance modifier should be used?
- a.T (no modifier)
- b.in TCorrect
- c.reified T
- d.out T
Why? this is the answer
The 'in' modifier is used for contravariant types that act as consumers, allowing a supertype (e.g., DataSink<Any>) to be used where a subtype (e.g., DataSink<String>) is expected, thus maximizing flexibility. The 'out' modifier is for producers, which would be incorrect for a consumer interface.
Just read this? Test yourself on what you have been reading.
Read the original → kotlinlang.org
- #kotlin
- #generics
- #api design
- #type system
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on kotlin — each one lists the topics its interview covers.
See open roles