和 java.lang.Class,java,casting"/>

首页 > 解决方案 > 无与伦比的类型:java.lang.Class和 java.lang.Class

问题描述

当我在 Arrays 类中使用一些方法时,我试图理解 java 中的强制转换。

我正在使用 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)

不会产生此错误。

我无法弄清楚为什么它不会产生此错误,有人可以解释吗?

标签: javacasting

解决方案


无法比较的类型错误告诉您,比较两个不可能相等的事物是没有意义的。

例如, 没有意义Integer.valueOf(0) == "",因为它们不是相同的类型;一个也不是另一个的超类型。它永远是错误的。

编译器将阻止a == bif 两者都是类类型(而不是接口),并且两者都a = bb = a被禁止。

因此,您被告知 aClass<? extends T[]>不能等于 a Class<Object[]>,因为您不能将一种类型的引用分配给另一种类型的变量。

通过强制转换对 的引用之一Object,编译器不再知道(/认为)这些类型绝对不相关 - 因为Object它是所有事物的超类型,所以“一个也不是另一个的超类型”不再正确 - 所以编译器允许检查。


该方法中多余的一件事U. 不需要它,只需Object[]在参数类型中使用即可。


推荐阅读