Reputation: 19185
In below program I fail to understand why there is ClassCastException
for cast from int.class
Update:
I should specify I know what primitive types are. What I don't understand is why int.class is provided with broken implementation?
public static void main(String[] args) {
System.out.println(DataType.INT.getValue(Integer.class));
System.out.println(DataType.INT.getValue(int.class));//Class cast exception here
}
enum DataType {
INT {
@Override
public <T> T getValue(Class<T> toClass) {
return toClass.cast(1000);//ClassCastException here for int.class
}
};
public abstract <T> T getValue(Class<T> toClass);
}
Upvotes: 5
Views: 2333
Reputation: 213401
Ok, after going through some links, and trying out some code, I found out that: -
int.class
== Integer.TYPE
== intint.class
!= Integer.class
So, the value of int.class
is Class object representing the type int
.
So, when you invoke your DataType.INT
with int.class
, the toClass
containts int
, on which you cannot invoke cast
. May be because it does not extend from Object
class. Because, cast
method internally uses isinstance
to check whether the invoking type is an Object
type or not.
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException();
return (T) obj;
}
So, if the type that invokes cast
is not an instance of Object
, which of course primitive
types are not, it will return false
, and hence a ClassCastException
.
Upvotes: 3
Reputation: 51030
I think it's because of the fact that int.class
is not same as Integer.class
.
Update
We can look at the cast method, it parameter is an Object
so it's obvious that 1000 get autoboxed, thus the actual argument to the method is an instance of Integer
:
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException();
return (T) obj;
}
Upvotes: 0
Reputation: 34397
I think this is what happening:
When you call return toClass.cast(1000);
, the literal 1000
is getting promoted to Integer
. Promotion rules are mentioned here : Java Language Specification.
Now when, cast
method is called on intClass
, its checks if argument(1000) is of same instance i.e. int.class
and it fails because its not.
On the other hand, when you cast to Integer.class
, it is successful as instance type does match.
So the ClassCastException
is coming because of Promotion
of literal 1000
to Integer
.
Upvotes: 0
Reputation: 19185
This happens because cast()
operation of Class
uses isInstance() method which returns false for primitive classes
.
If this Class object represents a primitive type, this method returns false.
Code for cast()
method is below
public T cast(Object obj) {
if (obj != null && !isInstance(obj))//It fails here since isInstance returns false
throw new ClassCastException();
return (T) obj;
Upvotes: 3
Reputation: 2102
A class cast exception is thrown by Java when you try to cast an Object of one data type to another. Here int is not an Object, it's a primitive which gets instantiated by some native code at runtime.
Upvotes: 0
Reputation: 85799
Integer
is a class wrapper for int
values, while int
is a primitive type, not a class. Don't confuse between primitive types and classes, for example, in code when you must use classes:
List<int> lstInteger; //won't compile!
List<Integer> lstInteger; //compiles fine
More info:
Think of int
type as a primitive C/C++ int type. Knowing this, the int is not a class, thus not having any attributes, any methods, just holding a integer value. On the other hand, java.lang.Integer
is a class wrapper for int
primitive type. This is in order to use the int
in cases where only object instances could be used. A good example of this is the generic system in Java that works only for classes (as proposed in your code example).
For deeper info in this, you can read from the Oracle Java Tutorial: Primitive Data Types.
Upvotes: 0