为什么不推荐使用 JUnit 4 中的 assertEquals(Object[], Object[])?

Why is assertEquals(Object[], Object[]) from JUnit 4 deprecated?

Eclipse 向我发出警告,指出类型 Assert 中的方法 assertEquals(Object[], Object[]) 已弃用。我正在使用 JUnit 4。

我在Eclipse中写了如下代码:

import org.junit.Test;
import org.junit.Assert;

public class Generics { 
    public <T> T[] genericArraySwap(T[] list, int pos1, int pos2) throws IndexOutOfBoundsException {
        ...
    }

    @Test
    public void genericArraySwapTest() {
        Integer[] IntegerList = {0, 1, 2, 3, 4};        
        Assert.assertEquals(new Integer[] {0, 1, 2, 4, 3}, genericArraySwap(IntegerList, 3, 4));
    }
}

谁能告诉我为什么不推荐使用这种方法,或者我应该改用什么方法?

由于 Java 类型系统缺乏表现力,它已被弃用。

而所有其他 assertEquals 方法将使用 ==(对于基元)或 equals(对于引用类型)来比较参数,您不想使用任何一个比较数组:所有数组都是 Object 的子类型(即它们是引用类型),并且不会覆盖 equals,因此使用 assertEquals 比较数组将检查两个数组是否是相同。

相反,您应该调用 assertArrayEquals,它比较数组是否具有相同的长度,如果是,则相应的数组元素是否相等。

理想情况下,您可以像这样指定参数类型:

assertEquals(T, T)

其中 T 是 "any subtype of Object, except for arrays"。但是在 Java 中您根本无法做到这一点;即使有一种方法可以表达这样的约束,您也无法阻止使用数组调用该方法,因为您始终可以将它们向上转换为 Objects.

您唯一能做的就是:

  • 提供接受 Objects
  • 的重载
  • 提供接受更具体类型的重载,并标记这些重载@Deprecated。要涵盖所有数组类型,您需要 9 个重载(每个原始数组类型 8 个;Object[] 1 个,涵盖所有其他引用类型)。

这不会阻止您调用 assertEquals(T[], T[]),但它确实通过编译器警告突出显示那里存在问题; Eclipse 中的黄色波浪线;等等

当然,如果您将数组向上转换为 Object,这将无济于事;但在大多数情况下,除非您真的打算调用该特定方法,否则您不会。