What does the type `T & Any` mean in Kotlin, and what problem does it solve?
answer
- T & Any = T but guaranteed non-null
- Intersection with Any strips nullability
- Only valid when T's bound is nullable (default Any?)
- Stable since Kotlin 1.7
- Main purpose: Java @NotNull interop overrides
basics
~10 sT & Any means "the type T, but guaranteed not null." If a generic type T could be null, writing T & Any forces it to be a non-null version of that type.
solid answer
~50 s`T & Any` is Kotlin's definitely-non-null type notation, stabilized in Kotlin 1.7. When a generic type parameter has a nullable upper bound (e.g. `<T>` with implicit bound `Any?`, or `<T : Comparable<T>?>`), the parameter itself is nullable, so you cannot guarantee a non-null value of it. `T & Any` is an intersection of `T` with `Any` (the non-nullable root of every type), which strips nullability: the result is always non-null no matter what `T` is bound to. Its main use is at the Java interop boundary: when you override a Java method whose return is annotated `@NotNull` but whose Java signature involves a nullable type variable, `T & Any` lets the Kotlin override declare a precise non-null return type. You can only write `T & Any` where `T` is a type parameter with a nullable bound.
code
kotlin · 8 lines// T has the default upper bound Any? (nullable)
fun <T> elvisLike(x: T, y: T & Any): T & Any = x ?: y
fun main() {
val a: Int = elvisLike(5, 6) // T = Int, fine
val b: Int = elvisLike(null, 12) // T = Int?, result still non-null Int
println("$a $b")
}go deeper
Can state that T & Any is 'T but not null' and recognize the syntax.
Explains it as an intersection with Any that strips nullability and knows it needs a nullable bound.
Connects it to the Java @NotNull interop motivation and the default Any? bound on type parameters.
Frames it within Kotlin's type lattice (intersection types, nullability as part of the type) and can reason about when the compiler warns or rejects it.
## The problem: generics with nullable bounds Every Kotlin type parameter has an **upper bound**. If you don't write one, the default is `Any?` (nullable). So: ```kotlin fun <T> firstOrNull(list: List<T>): T? = list.firstOrNull() ``` Here `T` could be substituted with `String`, but also with `String?`. Because the bound is `Any?`, the compiler treats a bare `T` as **possibly nullable** — you can't promise a value of type `T` is non-null. Sometimes you genuinely have a non-null value but the type system won't let you express it cleanly. Before Kotlin 1.7 the only workaround was `@Suppress` casts or wrapper bounds. ## The solution: `T & Any` `T & Any` is the **definitely-non-null** notation (stable since Kotlin 1.7). It is an **intersection type** of `T` and `Any`: - `Any` is the root of all **non-nullable** types (its nullable counterpart `Any?` is the root of everything). - Intersecting any type with `Any` removes the nullability: `String? & Any` is `String`, `T? & Any` is the non-null `T`. So `T & Any` is always a non-null type, regardless of how `T` is instantiated. ```kotlin fun <T> elvisLike(x: T, y: T & Any): T & Any = x ?: y ``` Here the result is guaranteed non-null even though `T` itself may be nullable. ## Where you can write it You may only use `T & Any` when `T` is a **type parameter whose upper bound is nullable** (the default `Any?`, or an explicit `Something?`). Writing `T & Any` on a parameter with a non-nullable bound is redundant and the compiler reports a warning. ## Primary use: Java interop The feature exists mainly to let Kotlin **override Java methods precisely**. If a Java generic method is annotated `@NotNull` on a return that is a type variable, the Kotlin override can declare `T & Any` so callers see a non-null type instead of a platform type. This is discussed in the follow-up questions. ## Recap of the keywords/operators involved - `&` — the intersection-type operator, used **only** in this definitely-non-null form. - `Any` / `Any?` — non-nullable vs nullable roots. - upper bound — the declared supertype of a type parameter.
- Since which Kotlin version is `T & Any` stable, and was there an earlier form?It was previewed in Kotlin 1.6 (with `-language-version 1.7`) and stabilized in Kotlin 1.7. There was no earlier sanctioned syntax; people used unchecked casts.
- What happens if you write `T & Any` when `T`'s bound is already non-null (e.g. `T : Any`)?It is redundant — the compiler emits a warning because the type is already non-null, so the intersection adds nothing.
Any? is 'a box that may be empty'; intersecting with Any is like stamping 'guaranteed full' on the box.
saying these in an interview costs you the question
- Thinking `T & Any` means 'T and also some Any object' rather than a nullability-stripping intersection
- Believing it works for any T regardless of bound
- Confusing it with `T!!` (not-null assertion) which is a runtime operator, not a type
- Saying it changes runtime behavior — it is a compile-time type, erased at runtime