androidengineers.Book a session

Generics and Type Parameters

Best Practices with Generics

article15 minMedium

Generic APIs should eliminate casts for callers

Name type parameters by their role when several are involved, and constrain them only as much as needed. A generic return type must be supported by an actual relationship to an input or stored value.

interface Repository<ID, Entity> {
    fun find(id: ID): Entity?
}

data class Lesson(val id: String, val title: String)
class Lessons(private val entries: Map<String, Lesson>) : Repository<String, Lesson> {
    override fun find(id: String): Lesson? = entries[id]
}

The repository fixes the relationship between its identifier and entity types. A function like fun <T> load(): T backed by an arbitrary cast promises more than it can guarantee unless a type-aware mechanism validates the result.

Do not force generics onto a domain-specific interface when concrete types communicate the contract better. Reuse should follow real common behavior.

Exercise

Add a repository using integer IDs and a different entity. Write callers that compile without casts and test a missing key.

Check: missing data should be represented explicitly; a generic type parameter is not permission to invent a value of that type.

Reference: Generics

YOUR LEARNING JOURNEY

0 of 110 available lessons completed

Progress saved in this browser. No account needed.
Best Practices with Generics | Kotlin Core Programming | Android Engineers