Member-only story

Effective Java! Combine Generics and Varargs Judiciously

Kyle Carter
6 min readMay 24, 2021

Today we look at the intersection of varargs and generics. Both of these features were introduced in Java 5 so they have a long history; however, as we will see in the review of this chapter, they don’t work great together. The reason for this is that varargs is a leaky abstraction. If you haven’t interacted with a varargs argument before it allows a client of your code to pass a variable number of arguments to your function. It accomplishes this by wrapping them up into an array on the other side. Unfortunately, this array, which feels like it should just be an implementation detail, is exposed and is what leads to the less than ideal interaction between generics and varargs. So let’s dig into the details.

We again find ourselves talking about non-reifiable types, which, as a refresher, are types that have less type information at runtime than at compile time. Arrays are reifiable whereas generics are not. If we create a function that takes a non-reifiable varargs parameter we are presented with a warning talking about Possible heap pollution. Heap pollution here refers to having a parameterized type that refers to an object that is not of that type. That sounds likely more confusing than it is so let's look at an example:

void badIdea(List<String>... stringLists) {
List<Integer> integerList = List.of(13);
Object[] objects = stringLists;
objects[0] = integerList;
String myString = stringList[0].get(0);
}

--

--

Kyle Carter
Kyle Carter

Written by Kyle Carter

I'm a software architect that has a passion for software design and sharing with those around me.

No responses yet