我正在使用Hamcrest 1.2庫編寫一些匹配器,但是我很難用Java通配符。當我嘗試編譯下面的代碼Java泛型和通配符:如何編譯此代碼?
public class GenericsTest {
public void doesNotCompile() {
Container<String> container = new Container<String>();
// this is the desired assertion syntax
assertThat(container, hasSomethingWhich(is("foo")));
}
// these two are a custom made class and matcher; they can be changed
public static class Container<T> {
public boolean hasSomethingMatching(Matcher<T> matcher) {
T something = null; // here is some application logic
return matcher.matches(something);
}
}
public static <T> Matcher<Container<T>> hasSomethingWhich(final Matcher<T> matcher) {
return new TypeSafeMatcher<Container<T>>() {
@Override
protected boolean matchesSafely(Container<T> container) {
return container.hasSomethingMatching(matcher);
}
};
}
// the following signatures are from the Hamcrest 1.2 library; they cannot be changed
public static <T> void assertThat(T actual, Matcher<? super T> matcher) {
}
public static <T> Matcher<? super T> is(T value) {
return null;
}
public interface Matcher<T> {
boolean matches(Object item);
}
public static abstract class TypeSafeMatcher<T> implements Matcher<T> {
@SuppressWarnings({"unchecked"})
@Override
public final boolean matches(Object item) {
return matchesSafely((T) item);
}
protected abstract boolean matchesSafely(T item);
}
}
它產生的編譯錯誤
$ javac GenericsTest.java
GenericsTest.java:7: <T>assertThat(T,GenericsTest.Matcher<? super T>) in GenericsTest cannot be applied to (GenericsTest
.Container<java.lang.String>,GenericsTest.Matcher<GenericsTest.Container<capture#928 of ? super java.lang.String>>)
assertThat(container, hasSomethingWhich(is("foo")));
^
1 error
如何修改代碼,以便它可以編譯?我已經嘗試了Container容器類和hasSomethingWhich方法簽名中? super
和? extends
的不同組合,但未能使其編譯(不使用顯式方法類型參數,但生成難看的代碼:GenericsTest.<String>hasSomethingWhich
)。
此外,還可以使用其他方法創建簡潔和可讀的斷言語法。無論什麼語法,它都應接受一個Container和一個匹配器來匹配容器中的元素。
修改後的版本在斷言類型轉換:'assertThat(容器,hasSomethingWhich((匹配器)是( 「富」))<超級字符串?>);' - 這太冗長合我的口味。我正在尋找能夠創建簡潔可讀的斷言API的東西。 – 2010-09-30 15:01:42
@Esko,演員是不必要的,並且被我的IDE無意中添加了。刪除它並更新了要點。 – 2010-09-30 15:09:24
我無法在你的要點中編譯代碼。你使用Hamcrest 1.1來編譯它嗎?使用原始帖子中的方法,這些方法取自Hamcrest 1.2。 1.2和1.1庫在使用'??時有所不同。超級「在匹配器中。 – 2010-09-30 15:18:19