Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
package demo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public class GenericsHell {
static class NumberLists<L extends List<T>,T extends Number> extends ArrayList<L> {}
static <L extends List<T>,T extends Number>
Set<NumberLists<L,T>> useList(L list) {
NumberLists<L,T> nl = new NumberLists<L, T>();
return Collections.singleton(nl);
// Note that this is not assignable to List<Number>
static List<? extends Number> makeList() {
if(Math.random()<.5) {
return new ArrayList<Integer>();
} else {
return new ArrayList<Double>();
static <L extends List<T>,T extends Number>
NumberLists<L,T> createAndAdd(L list) {
NumberLists<L,T> paraNL = new NumberLists<>();
return paraNL;
public static void main(String[] args) {
// Everything works with a concrete class
List<Integer> intList = new ArrayList<Integer>();
// Use with parametric functions
Set<NumberLists<List<Integer>,Integer>> concreteSet = useList(intList);
// Create related class of the same type
NumberLists<List<Integer>,Integer> concreteNL = concreteSet.iterator().next();
// But now I need to handle the case where the input is also parametric
List<? extends Number> numList = makeList();
// What is the type here? This is obviously an error
Set<NumberLists<? extends List<? extends Number>>,? extends Number> paramSet = useList(numList);
// Type should ideally be compatible with numList still
NumberLists<?,?> paraNL1 = paramSet.iterator().next();
// Captures don't match
// Can't even add numList to a NumberLists, since clusters don't match
NumberLists<?,?> paraNL2 = new NumberLists<>();
// Have to work around this with a parametric method that does both steps
NumberLists<?,?> paraNL3 = createAndAdd(numList);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.