The professional, friendly Java community. 21,500 members and growing!

The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.

Proper way to cast generics?

Every once in awhile you run into that bit of generics code that no matter what you do you can't get the code to behave without a forced cast. This is often due to the fact that generics are implemented through type erasure and don't exist at runtime. What I was wondering is why do my casts sometimes come up as syntax error requiring me to remove generic types from them?

For example; (These are all static members of a class with no generic type)

The cast above is of type (Collection). I want it to actually be of type (Collection<EventHandler<T>>) but when I add that generic info on it becomes a syntax error. Why is this?

Also is there a way to achieve the desired relationship here without resorting to casts? That relationship being that the map EVENT_HANDLERS contains a bunch of entries, each entry having a key that is a class subtype of event and a corresponding value of an EventHandler of that same event type.

I.E. <T extends Event> Map<Class<T>, Collection<EventHandler<T>>> *only that the T is a different subclass of Event for every entry.

As far as I'm aware the Java generic system is not powerful enough to express this concept directly.

Re: Proper way to cast generics?

The problem is that the type of the value of the map is the wildcarded type Collection<EventHandler<? extends Event>>. To this type you can cast. When you write your method, it returns a concrete type, the T which is contracted by the parameter. But java cannot determine if the value fetched by the key-value Class<T> would have the appropriate type. There exists no correlation between the key and the value. If you use wildcards and you want retrieve concrete types from any wildcarded type you must always cast. The bounded wildcard is for writing a common contract like an abstract class or an interface.