Member-only story

Effective Kotlin: Item 29 — Favor generic types

Matthew Dolan
2 min readDec 1, 2018

--

As with Java, there is no excuse in forcing clients to cast types when using your code especially when making a class generic is often trivial. Item 29 of Joshua Bloch’s brilliant Effective Java covers this by showing an example of generifying a Stack class which might look as follows in Kotlin:

class Stack(initialCapacity: Int = 16) {
private var elements = arrayOfNulls<Any?>(initialCapacity)
private var size = 0

val isEmpty = size == 0

fun push(e: Any) {
ensureCapacity()
elements[size++] = e
}

fun pop(): Any {
if (size == 0) throw EmptyStackException()
return (elements[--size] as Any).also {
elements
[size] = null // Eliminate obsolete reference
}
}

private fun ensureCapacity() {
if (elements.size == size)
elements = Arrays.copyOf(elements, 2 * size + 1)
}
}
val stack = Stack()
stack.push(5)
val value = stack.pop() as Int

The generic version might look as follows where as you cannot use a non reified type in Array we perform an unchecked cast :

class Stack<T : Any>(initialCapacity: Int = 16) {
@Suppress("UNCHECKED_CAST")
private var elements = arrayOfNulls<Any?>(initialCapacity) as Array<T?>
private var size = 0

val isEmpty = size == 0

fun push(e: T) {
ensureCapacity()
elements[size++] = e
}

fun pop(): T {
if (size == 0) throw EmptyStackException()
return (elements[--size] as

--

--

Matthew Dolan
Matthew Dolan

Written by Matthew Dolan

Matt Dolan has been eating doughnuts and developing with Android since the dark days of v1.6.

No responses yet