Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unchecked cast and generic class

Tags:

java

generics

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?

like image 714
Dmitry Zaytsev Avatar asked Sep 21 '25 04:09

Dmitry Zaytsev


2 Answers

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.

like image 197
Mike Samuel Avatar answered Sep 22 '25 19:09

Mike Samuel


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.

like image 42
John B Avatar answered Sep 22 '25 18:09

John B