Search code examples
javaeclipsereflectiontype-safety

Why does Eclipse complain about unsafe type casting?


Consider the following code:

public static <T extends SomeObject> List<T> getByClassName(String className) throws GetRecordsException {
    try {
        Class<T> clazz = (Class<T>) Class.forName(className).asSubclass(SomeObject.class);
        return getByClassName(clazz);
    } catch (ClassNotFoundException e) {
        throw new GetRecordsException("Failed to get class forName: " + className, e);
    }
}

Eclipse is highlighting the cast (Class<T>) with the following message:

Type safety: Unchecked cast from Class<capture#2-of ? extends SomeObject> to Class<T>

Why is this, considering that T is supposed to be guaranteed to extend from SomeObject in the method signature? What scenario might exist where this would be unsafe?


Solution

  • The caller of getByClassName specifies T to be any subclass of SomeObject, but that doesn't have to be the same subclass as the one named by className. Think of <T extends SomeObject> as indicating that the type variable T is another argument passed into the method call.

    So for example, an unsafe usage would be foo.<SomeObjectSubclass1>getByClassName("SomeObjectSubclass2") -- that syntax is how you specify type arguments explicitly, instead of letting them be inferred -- and then that'd return a List<SomeObjectSubclass1> that actually contained SomeObjectSubclass2, and everything would be a disaster.

    What you could do safely is let clazz be a Class<? extends SomeObject>, and then return a List<? extends SomeObject.