How do you declare a generic class in Kotlin, such as a simple Box<T> that holds a value of type T, and how do you create an instance of it?
answer
- Type param in <> after the class name
- No `new` — call the constructor like a function
- Inference fills in T from the argument
- T usable in properties, params, return types
- Erasure: can't do T() or is T
basics
~10 sPut a type parameter in angle brackets after the class name: class Box<T>(val value: T). Then create it like Box(42) or Box<String>("hi"); Kotlin usually infers the type for you.
solid answer
~40 sDeclare the type parameter in angle brackets right after the class name: `class Box<T>(val value: T)`. `T` is a placeholder that becomes a concrete type per instance. You reference `T` in the constructor, properties, and methods. Construct with `Box(42)` — the compiler infers `T = Int` from the argument — or state it explicitly: `Box<String>("hi")`. Unlike Java, Kotlin has no `new` keyword. A common gotcha: you cannot write `class Box<T>(val value: T = T())` to default-construct a `T`, because `T` is erased at runtime and the compiler has no constructor for an unknown type. Type parameters are conventionally single uppercase letters (`T`, `E`, `K`, `V`) but can be any valid identifier.
code
kotlin · 10 linesclass Box<T>(val value: T) {
fun get(): T = value
}
fun main() {
val ints = Box(42) // Box<Int>
val text = Box<String>("hi") // explicit
println(ints.get()) // 42
println(text.get()) // hi
}go deeper
Knows the class Box<T>(...) syntax, that there's no new, and that the type is usually inferred.
Explains where T can appear (properties, params, returns) and that all uses share one concrete type per instance.
Brings up erasure: why T()/is T don't work and how a factory or value argument fixes it.
Frames API design trade-offs — when to make a class generic vs. accept Any, and how erasure shapes the public surface.
## What a generic class is A **generic class** is a class parameterized by one or more **type parameters** — placeholders for a type that the caller fills in. This lets one class work safely with many element types without casting or `Any`. ## Syntax The type parameter list goes in angle brackets **immediately after the class name**: ```kotlin class Box<T>(val value: T) { fun get(): T = value fun isSame(other: T): Boolean = value == other } ``` - `T` is the **type parameter** (a name; `T` is just convention). - Inside the class body you may use `T` as a property type, parameter type, or return type. - The angle-bracket form `<T>` is the **declaration**; at the use site `Box<Int>` is a **type argument**. ## Creating instances — no `new` Kotlin has no `new` keyword. You call the constructor like a function: ```kotlin val a = Box(42) // T inferred as Int val b = Box<String>("hi") // T given explicitly val c: Box<Long> = Box(7L) // inferred from context ``` Type **inference** fills in `T` from the constructor argument or the expected type, so explicit `<...>` is usually optional. ## Referencing T across members `T` can appear anywhere a type is expected inside the class — in `val`/`var` properties, function parameters, and return types. All uses of `T` in one instance refer to the **same** concrete type. ## A key limitation: erasure Kotlin uses **type erasure** (inherited from the JVM): at runtime `Box<Int>` and `Box<String>` are the same raw `Box`. Therefore you **cannot** do `T()` to construct a `T`, call `T::class`, or use `is T` inside an ordinary class — there is no runtime type info for `T`. You must pass a value or a factory in instead. ## Conventional names `T` (type), `E` (element), `K`/`V` (key/value), `R` (result). Any identifier is legal, but stick to convention for readability.
- Why can't you write `class Box<T>(val value: T = T())`?Type parameters are erased at runtime, so the compiler has no constructor for the unknown type `T`. You must pass a value or a factory function instead.
- Does Kotlin need the `new` keyword to instantiate a generic class?No. Kotlin has no `new`; you call the constructor like a regular function, e.g. `Box(42)`.
A generic class is a labeled shipping box: the same box design carries anything, and the label (type argument) records what's inside so you can't pull out the wrong thing.
saying these in an interview costs you the question
- Putting the type parameter after the constructor parentheses instead of after the class name
- Using `new Box<Int>(...)` (Java syntax) in Kotlin
- Claiming you can default a property with `T()` inside the class
- Thinking each property could have a different concrete T within one instance