Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ParameterizedType.getRawType() returns j.l.r.Type, not Class<?>?

ParameterizedType parameterized =
    (ParameterizedType) List.class.getMethod("iterator").getGenericReturnType();
Type raw = parameterized.getRawType();

ParameterizedType#getRawType() returns a Type, not a Class<?> (although I get that java.lang.Class now implements Type). Is there a good reason why getRawType() doesn't declare its return type to be Class<?>? Are there extreme cases where getRawType()'s result might not be a Class<?>?

It's enough of a thrashing to work with j.l.r.Type as it is; this seems like an instance in which they could have saved us one downcast.

like image 597
pholser Avatar asked Apr 23 '11 21:04

pholser


3 Answers

It must return a Class object, there's no other way.

Why? Who knows, maybe some idealistic bias. If it returned Class, it would be the only appearance of Class in the new Type interfaces.

The real problem is the mixing of Class and Type. Previously, all types are represented in Class. It was already messy, but still tolerable. There weren't very many types.

With the new generic types, they should have designed a cleaner and true-to-specType hierarchy independent of Class. Instead they incorporated Class with Type and created more mess. The entire hierarchy just doesn't make sense. Anyone new to the subject and unaware of the history will be appalled by this nonsense.

I wouldn't hold the design of Type to a high standard. For example, ParameterizedType defines equals(), but not hashCode(). There's no way to have two implementations of ParameterizedType work in one hash map. And wildcard is also a type? Hell no.

And the name of the method getRawType() is just idiotic. It has nothing to do with raw type. It should be plainly named getClassOrInterface(). Would it be too verbose? Look at getActualTypeArguments() then. (And yeah, it returns actual arguments! Not fake ones!)

like image 88
irreputable Avatar answered Nov 03 '22 01:11

irreputable


I was thinking about this, and I have a hunch. Perhaps they wanted to leave the possibility open for future craziness like this:

public class Z<L extends List<?>> {
    L<Double> test;
}

This is not legal Java code, but I think it's clear what it would mean; new Z<ArrayList<?>>().test would be of type ArrayList<Double>.

If this were legal, ((ParameterizedType) test.getGenericType()).getRawType() would return a TypeVariable.

like image 22
Andy Avatar answered Nov 03 '22 01:11

Andy


Sun's implementation of ParameterizedType has defined the getRawType() method to return Class<?>. So it clearly returns only Class<?>

However, on my classpath there are a few more implementations of ParameterizedType - from hibernate-validator, from aspectj, hibernate-annotations, jaxb. Some of them return Class<?>, some - Type. I don't know how they are used though.

like image 23
Bozho Avatar answered Nov 03 '22 03:11

Bozho