> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Kotlin Covariance

Covariance in Kotlin is a type-system feature that preserves the subtyping relationship of generic type parameters. If type `A` is a subtype of type `B`, a covariant generic type `Generic<A>` is considered a subtype of `Generic<B>`. Kotlin implements covariance through two mechanisms: declaration-site variance using the `out` modifier, and use-site variance through type projections.

## Declaration-Site Variance

By marking a type parameter with `out` at the class or interface declaration, you instruct the compiler to restrict the usage of that type parameter strictly to **out positions** (return types and read-only `val` properties). The type can only be produced by the generic component, never consumed as an argument.

```kotlin theme={"dark"}
interface Producer<out T> {
    val defaultItem: T // Valid: T is in an 'out' position (read-only property)
    
    fun next(): T // Valid: T is in an 'out' position (return type)
    
    // fun add(item: T) // Compilation Error: T cannot occur in an 'in' position
}
```

Without covariance (invariance), generic types are strictly typed regardless of their type arguments. Covariance safely relaxes this strictness, allowing upcasting of the generic type.

```kotlin theme={"dark"}
open class Base
class Derived : Base()

// A covariant class
class Box<out T>(val value: T)

fun demonstrateCovariance() {
    val derivedBox: Box<Derived> = Box(Derived())
    
    // Valid assignment due to covariance: Box<Derived> is a subtype of Box<Base>
    val baseBox: Box<Base> = derivedBox 
}
```

## Type Safety and the `out` Restriction

The compiler enforces the "produce-only" rule to prevent heap pollution and runtime `ClassCastException`s. If a covariant type parameter were allowed in an `in` position (such as a function parameter or a mutable property), the type system could be compromised.

Using `var` with an `out` type parameter in a primary constructor is immediately illegal. The `var` keyword generates a setter, which places the type parameter in an `in` position, causing a compilation error on the property declaration itself.

```kotlin theme={"dark"}
open class Animal
class Dog : Animal()
class Cat : Animal()

// Compilation Error: Type parameter T is declared as 'out' but occurs in 'in' position
// class InvalidBox<out T>(var item: T) {
//     fun setItem(newItem: T) { ... } // Also Illegal: T in 'in' position
// }

// Hypothetical scenario demonstrating why the compiler forbids this:
class MutableBox<T>(var item: T) // Invariant class

fun demonstrateRestriction() {
    val dogBox: MutableBox<Dog> = MutableBox(Dog())
    
    // If MutableBox were covariant, the following would compile:
    // val animalBox: MutableBox<Animal> = dogBox 
    
    // Which would allow inserting a Cat into a Box<Dog>, breaking type safety:
    // animalBox.item = Cat() 
}
```

Because Kotlin restricts `out` parameters to read-only positions, a covariant `Box<Animal>` can only ever return an `Animal` (which is safely guaranteed to be a `Dog` in the underlying instance), and the compiler prevents you from writing a `Cat` into it.

## Use-Site Variance (Type Projections)

Certain types, such as `Array` or `MutableList`, must remain invariant at the declaration site because they both produce and consume elements. To achieve covariance for these types for a specific operation, Kotlin uses use-site variance, also known as type projections.

By applying the `out` modifier at the point of usage, you project the invariant type into a covariant one. This restricts the projected instance to its "produce" methods, effectively disabling any methods that consume the type parameter.

```kotlin theme={"dark"}
// Array is invariant at the declaration site: class Array<T>

fun copyElements(source: Array<out Animal>, destination: Array<Animal>) {
    // 'source' is a covariant type projection. 
    // We can safely read 'Animal' from it.
    for (i in source.indices) {
        destination[i] = source[i]
    }
    
    // Compilation Error: Cannot write to an 'out' projected array.
    // The setter expects 'Nothing' because the exact subtype is unknown.
    // source[0] = Dog() 
}

fun demonstrateUseSiteVariance() {
    val dogs: Array<Dog> = arrayOf(Dog(), Dog())
    val animals: Array<Animal> = arrayOf(Animal(), Animal())
    
    // Valid: Array<Dog> is passed where Array<out Animal> is expected
    copyElements(dogs, animals) 
}
```

## @UnsafeVariance

In specific architectural scenarios, a type parameter must be covariant at the declaration site, but technically needs to appear in an `in` position where the internal implementation guarantees type safety (e.g., checking equality). Kotlin provides the `@UnsafeVariance` annotation to suppress the compiler's variance conflict errors.

```kotlin theme={"dark"}
interface Collection<out E> {
    // E appears in an 'in' position, but is safe because 'contains' 
    // does not mutate the collection or cast the element unsafely.
    fun contains(element: @UnsafeVariance E): Boolean
}
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Kotlin Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
