Skip to content

Instantly share code, notes, and snippets.

@sbliven
Created November 15, 2016 10:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sbliven/f7babb729e0b1bee8d2dabe5ee979431 to your computer and use it in GitHub Desktop.
Save sbliven/f7babb729e0b1bee8d2dabe5ee979431 to your computer and use it in GitHub Desktop.
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>();
nl.add(list);
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<>();
paraNL.add(list);
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();
concreteNL.add(intList);
// 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
paraNL1.add(numList);
// Can't even add numList to a NumberLists, since clusters don't match
NumberLists<?,?> paraNL2 = new NumberLists<>();
paraNL2.add(numList);
// 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