10

How does this Java statement compile without warnings?

Class<Integer> x = int.class;

even though

Integer.class != int.class

Edit: Putting it a different way, it seems as though Integer.class and int.class have nothing in common (see comments below), so why does it make sense for this assignment to be possible?

5
  • 3
    the declaration of int.class is: public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int"); Since the type parameter doesn't truly matter and it's boxed, it's passable. Commented Feb 4, 2012 at 8:21
  • @bestsss: The value is boxed but other properties of the class do not hold. For example, one can use reflection to construct an Integer using Integer.class but there is no way to do this with int.class. Commented Feb 4, 2012 at 8:31
  • you can't construct an int at all via reflection, it's a primitive. The decision is quite simple: the primitives are boxed, so anywhere you can pass an int, an Integer would do (or vice verse). There is one exception though: simple class parameters are totally different, reflection like getMethod("xxx", Integer.class) won't work for xxx(int x). Commented Feb 4, 2012 at 8:38
  • I do understand that primitives are different, which is why this seems awkward. int.class is neither a superclass nor a subclass of Integer.class, Integer.class.isAssignableFrom(int.class) == false and int.class.cast(0) throws a ClassCastException. I don't see anything that can be done using int.class that relates to Class<Integer>. Commented Feb 4, 2012 at 9:05
  • Class is final (and doesn't have subclasses), the param type's only a compile time magic, it's lost during runtime and the boxing allows interoperability between primitives and wrappers. Since param types cannot be primitives the box class is used. That's all. For the record, I believe autoboxing was unnecessary and most of generic (aside co-variant return types) didn't improve the language, in 20++ years programming I've had 2 times "ClassCastException": once b/c using add instead of addAll, i.e. autocomplete, and the other due to wrong import. Typing all the <...> just make code unreadable Commented Feb 4, 2012 at 11:30

3 Answers 3

8

After a whole lot of searching, I came across this little snippet in the JLS, section 15.8.2 Class Literals:

If p is the name of a primitive type, let B be the type of an expression of type p after boxing conversion (§5.1.7). Then the type of p.class is Class<B>.

The spec doesn't explain why this is so, instead of Class<?> for example. I have also been unable to find any evidence that this is related to either generics or autoboxing.

Integer is a first-class object whereas int is a primitive type, and most methods of Class such as isInstance, isAssignableFrom and cast which operate on Objects are invalid in the context of int.class. Consequently, I do not see any reason why the type of int.class is Class<Integer>.

Sign up to request clarification or add additional context in comments.

Comments

4

Due to autoboxing. You can't use primitives in as type parameters, so the primitive is boxed into the wrapper.

9 Comments

Don't see why that would require autoboxing to work on class literals as well, though.
It looks like a workaround, because you can't have Class<int>. Of course, you can use Class<?>
Indeed seems like a hack, and I don't see any reason why Class<?> wouldn't suffice. See my comment above -- Integer.class and int.class aren't even similar as one might expect.
@Bozho, if you use Class<?> you can't declare anything like <T> T <Class<T>)
@bestsss: In what scenario is this useful for int.class? There is no way to return a primitive int for a generic return type.
|
4

I don't believe this has anything to do with autoboxing.

This is part of the rules of generics that it treats primitive types as their wrappers.

1 Comment

Is this specified somewhere in the JLS?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.