7

hamcrestライブラリには次のメソッドがあります。

package org.hamcrest.core

...

public static <T> Matcher<T> allOf(Matcher<? super T> first, Matcher<? super T> second) {
    List<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>(2);
    matchers.add(first);
    matchers.add(second);
    return allOf(matchers);
}

私のコードでは、firstbeingMatcher<Object>secondbeingを使用してこのメ​​ソッドを呼び出しますMatcher<SomeException>

そして今:

  • 1.6ターゲットのEclipseでコンパイルすると、になります<T> Matcher<SomeException>
  • 1.6ターゲットのjavac1.7でコンパイルすると、になります<T> Matcher<SomeException>
  • 1.6ターゲットのjavac1.6でコンパイルすると、<T> Matcher<Object>

問題は、<T>そのような場合はどうあるべきかということです。

私の理解では、javac 1.6にはバグがありMatcher<SomeException>、これは入力引数の一般的なタイプであり(SomeExceptionはObjectのサブタイプです)、返されるマッチャーがになることは100%確実Matcher<SomeException>です。

私は正しいですか?そして、javac 1.6を強制的に正しく動作させる方法はありますか?

4

2 に答える 2

3

コンパイラは、実際の引数に基づいて推論を行いますMatcher<Object> << Matcher<? super T>との初期制約から始まりMatcher<SomeException> << Matcher<? super T>ます。T << Objectそれから、制約とを推測しますT << SomeException最小の消去された候補セットが構築Objectされるときに削除されます。残りの候補は(最終的には:D)の代わりになります。SomeExceptionT

これまで、この場合、日食とJDK7が正しく動作することを示してきました。javacを強制的に正しく動作させる方法はないと思います。type引数を明示的に指定するか、JDK7(ソースとターゲットを6に指定)を使用できます。

于 2013-03-07T11:59:17.413 に答える
1

考慮すべきことが2つあります。

  1. まず、次のように使用できます。CoreMatcher.<SomeException>allOf(...)明示的に設定しTます。

  2. 第二に、型消去のため、ランタイムとして常に。がありMatcher<Object>ます。したがって、どちらの場合も、実行時の動作は同じです。

于 2013-03-07T12:02:21.110 に答える