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