Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Generic casting down generates warning, why?

I don't understand why the following code generates a warning.

interface Generic<T> {
}

interface A {
}

class B {
    Generic<A> c;

    <T extends A> B(Generic<T> a) {
        c = (Generic<A>) a; //warning here
    }

}

//Unchecked cast from Generic<T> to Generic<A>

In class B i'm only interested in using instances of Generic that are of type A. This warning suggests that I need to store the Generic argument as a T instead of A.

But this means I would have to declare B generic also, which seems to make things more complicated than they need to be.

like image 556
Mike Avatar asked Dec 22 '22 09:12

Mike


2 Answers

This is not down-casting, since Java generics are invariant: Generic<T> is not a subtype of Generic<A> even though T is a subtype of A. If you only need Generic methods that return A, you can use wildcard Generic<? extends A> in B constructor and in the field that stores the reference.

like image 186
Yardena Avatar answered Jan 06 '23 10:01

Yardena


Because a Generic<T> isn't a subtype of Generic<A> even if T is a subtype of A.

To illustrate this, consider String instance of Object:

List<String> listOfStrings = new ArrayList<String>();
List<Object> listOfObjects = (List<Object>)listOfStrings; // invalid
listOfObjects.add(new Date());
// now listOfStrings contain a date!

The compiler doesn't allow that cast, because it may cause the corruption of the original list. The JVM does not enforce generic bounds requirements at runtime.

The solution here is to declare the field c type as 'Generic`.

like image 28
notnoop Avatar answered Jan 06 '23 08:01

notnoop