简体   繁体   中英

Incomparable types: java.lang.Class<capture#1 of ? extends T[]> and java.lang.Class<java.lang.Object[]>

I was trying to understand casting in java while I was playing with a few methods inside the Arrays Class.

I am using IntelliJ IDEA and in the following method

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
    @SuppressWarnings("unchecked")
    T[] copy = ((Object)newType == (Object)Object[].class)
        ? (T[]) new Object[newLength]
        : (T[]) Array.newInstance(newType.getComponentType(), newLength);
    System.arraycopy(original, 0, copy, 0,
                     Math.min(original.length, newLength));
    return copy;
}

in the following line:

T[] copy = ((Object)newType == (Object)Object[].class)

IDE suggests that casting to (Object) is redundant.

Removing the casting is causing the following error.

Incomparable types: java.lang.Class<capture#1 of ? extends T[]> and java.lang.Class<java.lang.Object[]>

which made me thing that at first the error is correct, but experimenting for a while made me realise that I did not understand the issue because refactoring the code like ->

T[] copy = (newType == (Object)Object[].class)

and

T[] copy = ((Object)newType == Object[].class)

does NOT produce this error.

I cannot figure out why it does not produce this error, could someone explain?

The incomparable types error is telling you that it doesn't make sense to compare two things that cannot possibly be equal.

For example, there's no point in Integer.valueOf(0) == "" , because they're not the same types; nor is one a supertype of the other. It will always be false.

The compiler will prevent the a == b if both are class types (as opposed to interfaces), and both a = b and b = a would be disallowed.

So, you are being told that a Class<? extends T[]> Class<? extends T[]> cannot be equal to a Class<Object[]> , because you can't assign a reference of one type to a variable of the other type.

By casting one of the references to Object , the compiler no longer knows (/thinks) that the types are definitely not related - because Object is a supertype of everything, so "nor is one a supertype of the other" is no longer true - so the compiler allows the check.


One thing that is redundant in that method is U . There's no need for it, just use Object[] in the parameter type instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM