Todays Java Atrocity

class SomeLibraryClass<T> {

    public SomeLibraryClass(Class<T> klass) {
        // Use klass to overcome Java generics limitations
    }

}

public class Program {

    public static void main(String[] args) {
        // Cannot convert from Class<List> to Class<List<Integer>>: fair enough
        Class<List<Integer>> klass1 = List.class;
        // Integer and List cannot be resolved: huh, that's an odd error
        Class<List<Integer>> klass2 = List<Integer>.class;
        // Cannot cast from Class<List> to Class<List<Integer>>: they should be equivalent after erasure, but fine
        Class<List<Integer>> klass3 = (Class<List<Integer>>)List.class;
        // This works! Awesome! But it's dead ugly (and unchecked of course), and why should I have to cast
        // to Class<?> before what I want? This means the castable-to relationship is >not transitive<!
        Class<List<Integer>> klass4 = (Class<List<Integer>>)(Class<?>)List.class;
    }

}

One thought on “Todays Java Atrocity

  1. Hey Max! Squirrel pointed me here to the post.

    Basically, you are right. Generics are quite annoying. It feels like they got generics about 90% right.

    As a side note, you could reduce your parenthesis by using:

    Class<List<Integer>> klass5 = (Class) List.class;

    But, compiler-wise it is the same as your klass4 example. You are just forcing the assignment to implicitly perform the cast, rather than making it explicit on the RHS.

    There are some Java 7 notions on the subject:

    Reified generics (which may directly address the root problem of your example)

    Self types (depending on just what you are looking for)

Comments are closed.