Reputation: 183
Yet another Java Generics unchecked cast question coming up:
We have something like the following:
public abstract class A<T extends A> {
public final T doSomething() {
return (T)this; //unchecked cast A<T> to T
}
}
So, is this unchecked cast something we can surpress or is there really a case where this can fail?
Upvotes: 0
Views: 592
Reputation: 180141
Yes, it absolutely can fail. Example:
public class B extends A<B> {
// empty
}
public class C extends A<B> {
// empty
}
public class AnotherClass {
public void someMethod() {
A<B> c = new C();
B b = c.doSomething(); /* ClassCastException */
}
}
Note that @awksp's suggested change to ...
abstract class A<T extends A<T>> { /* ... */ }
... does not rescue this example. With that change, the type safety diagnostic in A.doSomething()
remains the only one, and of course AnotherClass.someMethod()
still throws ClassCastException
.
Upvotes: 8
Reputation: 85823
is there really a case where this can fail?
Sure. Here's an example:
class A<T extends A<?>> {
@SuppressWarnings("unchecked")
T get() {
return (T) this;
}
}
class B<T extends A<T>> extends A<T> {
}
class C<T extends B<T>> extends A<T> {
}
Now C's method will return a C, but C isn't a legal substitution for T extends B<T>
, since C doesn't extend B.
Upvotes: 2