I have a class:
public class SomeClass <TView extends View>{
private TView tv;
public SomeClass(View v){
tv=(TView) v; //unchecked cast warning
}
}
View
is a concrete class (not abstract, not interface).
Question is
Why do I get an unchecked cast warning, even if TView
extends View
?
The cast is not enforced at runtime.
Your class post-erasure looks like:
public class SomeClass {
private View tv; // Post-erasure, TView -> View
public SomeClass(View v){ // Post-erasure, TView -> View
tv=(View) v; //unchecked cast warning due to cast of View to View
}
}
Note that post-erasure, the constructor is casting a value of type View
to type View
since that is the lower-bound for <TView extends View>
.
Casting View
to View
does not check anything at runtime, which is why you get the warning.
Yeah, but View
does not extend TView
which means that an instance of View
might not be an instance of TView
.
Imagine View
, and ViewA extends View
and ViewB extends View
If you create a SomeClass<ViewA>
and call new SomeClass<ViewA>((View)new ViewB())
you could cause some issues. For example, the below test will throw a ClassCastException
at the line ViewA oa = o.getT();
class View{}
class ViewA{}
class ViewB{}
class Other<T extends View>{
T t;
Other(View view){
t= (T)view;
}
T getT(){
return T;
}
}
@Test
public void testIt(){
ViewA a = new ViewA();
ViewB b = new ViewB();
Other<ViewA> o = new Other<ViewA>((View)b);
ViewA oa = o.getT();
}
The above compile put will fail due to the ClassCastException
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With