web-dev-qa-db-ja.com

JUnit 4のassertEquals(Object []、Object [])が非推奨になるのはなぜですか?

Eclipseは、タイプAssertのメソッドassertEquals(Object[], Object[])が非推奨であることを示す警告を表示しています。 JUnit4を使用しています。

私は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));
    }
}

このメソッドが非推奨になった理由や、代わりにどのメソッドを使用すべきかを誰かに教えてもらえますか?

12
karposhark

Java型システムの表現力が不足しているため、非推奨になりました。

他のすべてのassertEqualsメソッドは_==_(プリミティブの場合)またはequals(参照型の場合)を使用してパラメーターを比較しますが、配列の比較にはどちらも使用しないでください。 :すべての配列はObjectのサブタイプであり(つまり、参照型です)、equalsをオーバーライドしないため、assertEqualsを使用して配列を比較すると、2つの配列が同一。

代わりに、assertArrayEqualsを呼び出す必要があります。これは、配列の長さが同じかどうか、同じ長さの場合は、対応する配列要素が等しいかどうかを比較します。

理想的には、次のようなパラメータタイプを指定できます。

_assertEquals(T, T)
_

ここで、Tは「配列を除くObjectの任意のサブタイプ」です。しかし、Javaではそれを行うことはできません。そのような制約を表現する方法があったとしても、メソッドが配列で呼び出されるのを防ぐことはできません。なぜなら、それらはいつでもObjectsにアップキャストできるからです。

あなたができる唯一のことは:

  • Objectsを受け入れるオーバーロードを提供します
  • より具体的なタイプを受け入れるオーバーロードを提供し、これらのオーバーロードに_@Deprecated_のマークを付けます。すべての配列タイプをカバーするには、9つのオーバーロードが必要です(プリミティブ配列タイプごとに8つ、他のすべての参照タイプをカバーする_Object[]_に1つ)。

これは、assertEquals(T[], T[])の呼び出しを妨げるものではありませんが、コンパイラの警告を介して、そこに問題があることを強調しています。 Eclipseの黄色い波線。等.

もちろん、配列をObjectにアップキャストした場合、これは役に立ちません。ただし、その特定のメソッドを実際に呼び出すつもりがない限り、ほとんどの場合、そうしません。

9
Andy Turner