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

2022-09-04 21:18:53

Eclipse 给了我一个警告,说该类型中的方法已被弃用。我正在使用JUnit 4。assertEquals(Object[], Object[])Assert

我在 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));
    }
}

有人可以告诉我为什么这种方法被弃用或我应该使用什么方法吗?


答案 1

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

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

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

理想情况下,您将能够指定如下参数类型:

assertEquals(T, T)

其中 是 “的任何子类型,数组除外”。但是你根本无法在Java中做到这一点。即使有一种方法可以表达这样的约束,你也无法阻止使用数组调用该方法,因为你总是可以将它们向上投影为s。TObjectObject

您唯一能做的就是:

  • 提供接受 s 的重载Object
  • 提供接受更特定类型的重载,并标记这些重载。要涵盖所有数组类型,您需要 9 个重载(每个基元数组类型 8 个;1 个用于 ,涵盖所有其他引用类型)。@DeprecatedObject[]

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

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


答案 2

推荐