Search code examples
javainterfacemultiple-inheritance

Unchecked Cast Warning: interface as return value, stored in Class implementing said interface


My situation is, I have a function

public static MyInterface doSomething() {...}

and a Class

MyList<O extends MyObject> extends MyListObject<O> implements MyInterface

and:

  • MyObjectA extends MyObject
  • MyListObject just implements the interfaces Collection<O> and List<O>

My Problem now is, that following code

MyList<MyObjectA> var = (MyList<MyObjectA>)doSomething();

produces a

Type safety: Unchecked cast from MyInterface to MyList<MyObjectA>

warning.
Why is that so? I mean doOperation() returns a MyInterface type and MyList implements said interface...

I hope my code example explains the complete relation between all classes and interfaces and that I haven't missed anything.


Solution

  • Essentially, the type in a cast may not contain <…>, unless it is <?>. (There are exceptions to this rule, but they’re corner cases, and not relevant here.)

    Generics are a compile-time type checking mechanism. At runtime, there does not exist a MyList<MyObjectA> class, due to type erasure. There is only a single MyList class.

    This means the compiler can only generate this code:

    (MyList<?>) doSomething();
    

    Attempting to force the compiler to assume that the result has a specific generic type is unsafe, because the code which will do the cast cannot check for that. Thus, your cast is an unchecked cast.

    The safe way to do this is to perform non-generic casts:

    MyList<MyObjectA> var = new MyList<>();
    MyList<?> list = (MyList<?>) doSomething();
    for (Object element : list) {
        var.add((MyObjectA) element);
    }
    

    Caution: var is now a reserved keyword in Java. You should avoid using it as a variable name.