The out keyword means the generic type is covariant. It can only be returned (produced) but not consumed (accepted as input). This ensures type safety when using subtypes.
Click to reveal answer
beginner
Why is covariance useful in Kotlin?
Covariance allows you to use a subtype where a supertype is expected, especially for read-only data. For example, a List<Dog> can be used as a List<Animal> if the list is covariant.
Click to reveal answer
intermediate
Given interface Producer<out T>, can you pass T as a function parameter inside this interface?
No. Because T is declared with out, it can only be returned (produced), not consumed as input parameters. This prevents type errors.
Click to reveal answer
intermediate
How does Kotlin enforce covariance at compile time?
Kotlin restricts usage of the covariant type parameter to only output positions (like return types). If you try to use it as an input parameter, the compiler will show an error.
Click to reveal answer
intermediate
What is the difference between out and in variance in Kotlin?
out means covariance (can only produce values), in means contravariance (can only consume values). They control how generic types relate to subtyping.
Click to reveal answer
What does the out keyword in Kotlin generics allow?
AUsing a subtype where a supertype is expected (covariance)
BUsing a supertype where a subtype is expected (contravariance)
CAllowing both input and output of generic type
DDisabling generics
✗ Incorrect
out enables covariance, allowing a subtype to be used where a supertype is expected.
Can a covariant generic type parameter be used as a function parameter inside the class/interface?
AYes, always
BNo, it can only be returned
COnly if marked with <code>in</code>
DOnly if the function is private
✗ Incorrect
Covariant type parameters (out) can only be used in output positions, like return types, not as input parameters.
Which of these is a correct example of covariance in Kotlin?
Ainterface Producer<in T> { fun produce(): T }
Binterface Consumer<out T> { fun consume(t: T) }
Cinterface Producer<out T> { fun produce(): T }
Dinterface Consumer<in T> { fun consume(): T }
✗ Incorrect
Producer with out T can produce values of type T. Consumer with out T is invalid because it consumes T.
What error will Kotlin show if you try to use a covariant type as a function parameter?
AVariance conflict error
BType mismatch error
CNull pointer exception
DNo error
✗ Incorrect
Kotlin shows a variance conflict error because covariant types cannot be used as input parameters.
If List is declared as interface List, what does this mean?
AYou can add elements of type T to the list
BThe list is mutable
CYou can neither add nor read elements
DYou can only read elements of type T from the list
✗ Incorrect
Covariant out T means you can safely read elements of type T but not add them.
Explain what 'out variance' (covariance) means in Kotlin generics and why it is useful.
Think about how you can safely use subtypes when returning values.
You got /4 concepts.
Describe a situation where using 'out' variance in Kotlin prevents type errors.
Consider a list of animals and dogs.
You got /3 concepts.
Practice
(1/5)
1. What does the out keyword mean in Kotlin generics?
easy
A. The generic type can be used for both input and output.
B. The generic type is used only for input (consuming values).
C. The generic type is used only for output (producing values).
D. The generic type is mutable and can be changed.
Solution
Step 1: Understand the meaning of out in Kotlin generics
The out keyword means the generic type is only used to produce values, not consume them.
Step 2: Compare options with this meaning
The generic type is used only for output (producing values). correctly states that the generic type is used only for output (producing values). Other options describe input or mutability, which are incorrect.
Final Answer:
The generic type is used only for output (producing values). -> Option C
Quick Check:
Out variance = output only [OK]
Hint: Remember: out means output only, no input allowed [OK]
Common Mistakes:
Confusing out with in variance (input)
Thinking out allows mutation
Assuming out means both input and output
2. Which of the following is the correct syntax to declare a covariant generic interface in Kotlin?
easy
A. interface Producer { fun produce(): T }
B. interface Producer { fun produce(): T }
C. interface Producer<T> { fun produce(input: T) }
D. interface Producer<T> { fun produce(): T }
Solution
Step 1: Identify covariance syntax in Kotlin
Covariance is declared using out before the generic type parameter, like out T.
Step 2: Match syntax with options
interface Producer { fun produce(): T } correctly uses out T and a function that returns T. Other options either use in or lack the out keyword.
Final Answer:
interface Producer<out T> { fun produce(): T } -> Option A
Quick Check:
Covariant syntax = out T [OK]
Hint: Covariant generics use 'out' before the type parameter [OK]
Common Mistakes:
Using 'in' instead of 'out' for covariance
Omitting 'out' keyword
Confusing input and output functions
3. What will be the output of the following Kotlin code?
interface Source {
fun next(): T
}
class StringSource : Source<String> {
override fun next() = "Hello"
}
fun printSource(source: Source<Any>) {
println(source.next())
}
fun main() {
val stringSource = StringSource()
printSource(stringSource)
}
medium
A. Hello
B. Compilation error due to type mismatch
C. Runtime error
D. Prints null
Solution
Step 1: Understand covariance in the interface
The interface Source is declared with out T, so Source<String> can be used where Source<Any> is expected.
Step 2: Trace the function call and output
stringSource returns "Hello" from next(). Passing it to printSource works due to covariance, so it prints "Hello".
Hint: Covariance lets Source<String> be used as Source<Any> safely [OK]
Common Mistakes:
Expecting a compilation error due to type mismatch
Confusing covariance with invariance
Thinking runtime error occurs
4. Identify the error in this Kotlin code using out variance:
interface Producer {
fun produce(input: T): T
}
medium
A. No error, code is correct
B. Missing return type in function produce
C. Interface must be declared with in instead of out
D. Cannot use T as a function parameter when declared with out
Solution
Step 1: Check usage of generic type T with out variance
When T is declared with out, it can only be used as a return type, not as a function parameter.
Step 2: Analyze the function signature
The function produce(input: T): T uses T as a parameter, which is not allowed with out T.
Final Answer:
Cannot use T as a function parameter when declared with out -> Option D
Quick Check:
Out variance forbids T as input parameter [OK]
Hint: Out means T only as output, not input parameters [OK]
Common Mistakes:
Ignoring variance rules for function parameters
Thinking out allows input parameters
Confusing in and out variance
5. Given the following Kotlin classes:
open class Animal
class Dog : Animal()
interface Producer {
fun produce(): T
}
fun feedAnimals(producer: Producer<Animal>) {
val animal = producer.produce()
println("Feeding an animal")
}
fun main() {
val dogProducer: Producer<Dog> = object : Producer<Dog> {
override fun produce() = Dog()
}
feedAnimals(dogProducer)
}
Why does this code compile and run without errors?
hard
A. Because Kotlin ignores variance annotations at runtime
B. Because Producer is covariant with out, allowing Producer<Dog> where Producer<Animal> is expected
C. Because produce() returns a generic type without restrictions
D. Because Dog is a superclass of Animal, so substitution is allowed
Solution
Step 1: Understand covariance with out keyword
The interface Producer is declared with out T, making it covariant. This means Producer<Dog> can be used where Producer<Animal> is expected.
Step 2: Analyze class hierarchy and function call
Dog is a subtype of Animal. The function feedAnimals expects Producer<Animal>, but dogProducer is Producer<Dog>. Covariance allows this substitution safely.
Final Answer:
Because Producer is covariant with out, allowing Producer<Dog> where Producer<Animal> is expected -> Option B
Quick Check:
Covariance allows subtype substitution [OK]
Hint: Covariance lets Producer<Dog> be used as Producer<Animal> [OK]
Common Mistakes:
Thinking Dog is superclass of Animal
Ignoring variance and expecting error
Assuming produce() return type is unrestricted
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.