Strange error with a list of common classes

I have a list of class objects, all of which require a class extension with a common type. Here is my code:

private final List<Class<? extends A<?>>> CLASS_LIST =
        Arrays.asList(B.class, C.class, D.class);

// Base class
private abstract class A<T extends Object> {}

// Some class that extends A
private class B extends A<String> {}

// Some other class that extends A
private class C extends A<String> {}

// A class that extends A, but with a different type than the first two
private class D extends A<OtherClass> {}

private static class OtherClass {}

This works fine, but if I remove D.class from the list, I get an error:

Incompatible types, Required A<?>, found A<String>

Why is this happening? I assume Java passes a type ... but why? And is there a way around this? I found that if I use it List<?>, it works in all cases, but then I lose type safety.

EDIT: Also, if I have this method:

private void Check(){
    A a = new B();

    if(CLASS_LIST.contains(a.getClass())){
        // Do something
    }
}

This gives me a warning about a suspicious call List.contains(...). However, if I use List<?>, the warning goes away ... why is this?

EDIT2: Java 1.8.0_51-b16 compiles, but Java 1.7.0_79 gives an error.

+4
2

,

Arrays.asList(B.class, C.class)

(1.7, 1.8 ) Class<? extends A<String>> , . , :

Arrays.<Class<? extends A<?>>>asList(B.class, C.class)
+2

JDK.

Arrays.asList ArrayList - , Array, java.util.ArrayList.

public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

/**
* @serial include
*/
private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable
{
    ....
}

ArrayList remove, .

-1

Source: https://habr.com/ru/post/1653276/


All Articles