Reputation: 2647
The following code generates a warning Unchecked cast: 'T' to 'U'
in IntelliJ IDEA:
interface A {}
class B<T extends A, U extends A> {
void f() {
final T t = null;
final U u = (U) t;
}
}
This doesn't make sense to me, since T
and U
are defined as the same type. What is the problem?
Upvotes: 2
Views: 1022
Reputation: 3170
Parent:
interface A {
}
Child:
class B implements A {
}
class C implements A {
}
In the above example A is parent B and C.
Example:
The below code will works fine.
A a = new B();
B b = (B)a;
This will trigger class Cast Exception.
B b = new B();
C c = (C) b;
You can't type cast with your Siblings type. This is because You may try to access the methods/properties that may present in the resultant class.
Same thing can be to String,Integer,Object. Object is parent
Integer & String are the child for Object class but you cannot cast these classed.
Upvotes: 1
Reputation: 140309
final T t = null;
final U u = (U) t;
Although this is unchecked, this is actually safe, because null
can be cast to any reference type without a ClassCastException
.
However, the compiler doesn't consider the value of a non-null reference when you cast it: it's simply "some" T
. This is an example of where you, the programmer, know more about the types than the compiler, because you know that t == null
, so you can legitimately ask the compiler to trust you by adding casts and @SuppressWarnings
.
But if t
were non-null, this wouldn't always be safe. T
and U
are different types: they are "something that extends A
" and "something (maybe the same, maybe not) that extends A
".
To make this a little bit more concrete, here's an equivalent example:
class B<T extends Serializable, U extends Serializable> {
U method(T t) {
return (U) t;
}
}
String s = new B<Integer, String>().method(1);
This will fail with a ClassCastException
, because an Integer
isn't a String
.
If you don't want them to be different types, remove one of them (and, of course, the cast).
Upvotes: 0
Reputation: 11975
While both T
and U
extend A
, they are not the same type. Hence you cannot cast from one to the other.
Consider:
class D implements A {}
class E implements A {}
B<D, E> b;
You cannot cast from D to E.
Upvotes: 1
Reputation: 393781
T
and U
are not defined as the same type. They are both defined as extends A
, which means T
and U
can be unrelated classes that implement the A
interface. Hence the cast is not safe.
The only safe cast you can do is to cast references of type T
or U
to type A
. Of course you don't need such a cast. You can simply assign them to a variable of type A
.
Upvotes: 5