Biorąc pod uwagę następujący przykład (użycie JUnit z dopasowaniami Hamcrest):
Map<String, Class<? extends Serializable>> expected = null;
Map<String, Class<java.util.Date>> result = null;
assertThat(result, is(expected));
Nie kompiluje się z assertThat
sygnaturą metody JUnit :
public static <T> void assertThat(T actual, Matcher<T> matcher)
Komunikat o błędzie kompilatora to:
Error:Error:line (102)cannot find symbol method
assertThat(java.util.Map<java.lang.String,java.lang.Class<java.util.Date>>,
org.hamcrest.Matcher<java.util.Map<java.lang.String,java.lang.Class
<? extends java.io.Serializable>>>)
Jeśli jednak zmienię assertThat
podpis metody na:
public static <T> void assertThat(T result, Matcher<? extends T> matcher)
Następnie kompilacja działa.
Więc trzy pytania:
- Dlaczego dokładnie nie kompiluje się bieżąca wersja? Chociaż niejasno rozumiem tu kwestie kowariancji, z pewnością nie mógłbym tego wyjaśnić, gdybym musiał.
- Czy zmiana
assertThat
metody na ma jakiś minusMatcher<? extends T>
? Czy są inne przypadki, które by się zepsuły, gdybyś to zrobił? - Czy jest jakiś sens uogólnienia
assertThat
metody w JUnit?Matcher
Klasa nie wydaje się potrzebne, ponieważ JUnit wywołuje metodę zapałek, który nie jest wpisany na wszelkie generycznych, a po prostu wygląda jak próba wymuszenia typu bezpieczeństwa, który nic nie robi, boMatcher
po prostu nie będzie w rzeczywistości dopasuj, a test się nie powiedzie. Brak niebezpiecznych operacji (a przynajmniej tak się wydaje).
Dla odniesienia, oto implementacja JUnit assertThat
:
public static <T> void assertThat(T actual, Matcher<T> matcher) {
assertThat("", actual, matcher);
}
public static <T> void assertThat(String reason, T actual, Matcher<T> matcher) {
if (!matcher.matches(actual)) {
Description description = new StringDescription();
description.appendText(reason);
description.appendText("\nExpected: ");
matcher.describeTo(description);
description
.appendText("\n got: ")
.appendValue(actual)
.appendText("\n");
throw new java.lang.AssertionError(description.toString());
}
}