Несравненные типы: java .lang.Class и java .lang.Class <java .lang.Object []> - PullRequest
1 голос
/ 09 февраля 2020

Я пытался понять приведение в java, когда играл с несколькими методами внутри класса Arrays.

Я использую IntelliJ IDEA и в следующем методе

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;
}

в следующей строке:

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

IDE предполагает, что приведение к (Object) является избыточным.

При удалении приведении возникает следующая ошибка.

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

что сначала показало, что ошибка верна, но эксперименты на некоторое время заставили меня понять, что я не понял проблему, потому что рефакторинг кода, например, ->

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

и

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

не вызывает ли НЕ эту ошибку.

Не могу понять, почему она не приводит к этой ошибке, может кто-нибудь объяснить?

1 Ответ

1 голос
/ 09 февраля 2020

Ошибка несопоставимых типов говорит о том, что нет смысла сравнивать две вещи, которые не могут быть равны.

Например, в Integer.valueOf(0) == "" нет смысла, потому что они не одинаковые типы; ни один не является супертипом другого. Это всегда будет false.

Компилятор предотвратит a == b, если оба являются типами классов (в отличие от интерфейсов), и оба a = b и b = a будут запрещены.

Итак, вам говорят, что Class<? extends T[]> не может быть равен Class<Object[]>, потому что вы не можете назначить ссылку одного типа на переменную другого типа.

Путем приведения одного из ссылки на Object, компилятор больше не знает (/ думает), что типы определенно не связаны - потому что Object является супертипом всего, поэтому «ни один не является супертипом другого» больше не верно - таким образом, компилятор допускает проверку.


Одна вещь, которая является избыточной в этом методе, это U. В этом нет необходимости, просто используйте вместо этого Object[] в качестве параметра.

...