Write a generic function whose type parameter must be both a `CharSequence` and `Comparable<T>`. Show exactly where the `where` clause goes in a function and in a class declaration.
answer
- Parameter brackets stay UNBOUNDED: `<T>`
- Function: after return type, before body
- Class: after supertypes, before `{`
- Comma-separated `T : X, T : Y`
- Can constrain several params: `T : A, U : B`
basics
~10 sDeclare the parameter as plain <T>, then after the return type (function) or the supertypes (class) add where T : CharSequence, T : Comparable<T> before the body.
solid answer
~50 sFor a **function**, the `where` clause comes after the parameter list and return type and before the body: `fun <T> f(x: T): R where T : CharSequence, T : Comparable<T> { ... }`. For a **class/interface**, it comes after the primary constructor and the supertype list and before the class body: `class Box<T>(val v: T) where T : CharSequence, T : Comparable<T> { ... }`. In both cases the bracketed parameter must be written **without** a bound (just `<T>`), because the bounds now live in `where`. Each constraint is a separate `T : SomeType` joined by commas, and you may constrain several different parameters in the same clause (`where T : A, U : B`). The clause expresses a conjunction; mixing it with a single inline bound on the same parameter is redundant and not how it is done.
code
kotlin · 13 linesfun <T> betweenInclusive(x: T, lo: T, hi: T): Boolean
where T : CharSequence, T : Comparable<T> =
x >= lo && x <= hi
class Sorted<T>(initial: List<T>)
where T : CharSequence, T : Comparable<T> {
val data = initial.sorted()
}
fun main() {
println(betweenInclusive("m", "a", "z")) // true
println(Sorted(listOf("b", "a")).data) // [a, b]
}go deeper
Can copy the function form and put a comma-separated where after the return type.
Places where correctly in both function and class forms and keeps the parameter unbounded in brackets.
Knows the at-most-one-class rule and that several parameters can share one where.
Explains the parser rationale for placement and the JVM single-inheritance constraint that limits class bounds.
## Function form The `where` clause attaches to the function **signature**, positioned after the return type and before the `=` or `{`: ```kotlin fun <T> clamp(value: T, lo: T, hi: T): T where T : CharSequence, T : Comparable<T> { return when { value < lo -> lo value > hi -> hi else -> value } } ``` Note: `T` in the brackets carries **no** bound — all bounds are in `where`. ## Class / interface form Here `where` comes after the primary constructor parameters and the supertype list, before the body: ```kotlin class SortedLabel<T>(val label: T) where T : CharSequence, T : Comparable<T> { fun isBlank() = label.isEmpty() } interface Repo<ID> where ID : Comparable<ID>, ID : java.io.Serializable ``` ## Rules to remember - The parameter in `<...>` must be **unbounded** when you use `where` for it; you do not also write `<T : X>`. - Constraints are **comma-separated**, each in the form `Param : Type`. - You can constrain **multiple** parameters at once: ```kotlin fun <T, U> copy(src: T, dst: U) where T : CharSequence, U : Appendable ``` - At most **one** of the constraints may be a class (non-interface) type; the rest must be interfaces, because Kotlin (like the JVM) has single inheritance of classes but multiple interfaces. - The clause is the same conjunction whether on a function, class, interface, or even a property's generic accessor receiver — semantics never change. ## Why placement matters Kotlin parses the supertype/return-type list first; the `where` keyword unambiguously begins the constraint block, which is why it must follow them and precede the body or `=`.
- Can two of the `where` constraints both be (non-interface) classes?No. At most one constraint may be a class; the rest must be interfaces, mirroring single class inheritance on the JVM.
- Is it legal to write `<T : CharSequence>` AND a `where T : Comparable<T>` together?It is technically rejected when you also put `T` in `where`; the idiomatic and required form is to leave `T` unbounded in brackets and place all bounds in `where`.
saying these in an interview costs you the question
- Putting the bound in the brackets and in `where` for the same parameter
- Placing `where` before the return type or before supertypes
- Claiming you can list two classes (non-interfaces) as bounds
- Forgetting that one `where` can constrain multiple parameters