Generics Hell - 我如何将joda.DateTime传递给Hamcrest Matcher.greaterThan?

时间:2011-11-01 17:13:20

标签: java generics jodatime hamcrest

JodaTime已经

public final class DateTime extends BaseDateTime {...}

直到

public interface ReadableInstant extends Comparable<ReadableInstant>

Hamcrest

public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<? super T>
    greaterThan(T value) {...}

如果我尝试

greaterThan(new DateTime());

然后我得到一个编译错误(Eclipse给出最多的线索)

  

Matchers类型的泛型方法greaterThan(T)不适用   为参数(DateTime)。推断类型DateTime不是有效替代   对于有界参数&gt;

我是否正确地认为greaterThan的签名实际应该是

public static <T extends java.lang.Comparable<? super T>> org.hamcrest.Matcher<? super T>     
    greaterThan(T value)

?是否有一种方法可以将这些组合在一起,而不是将其转换为原始Comparable

2 个答案:

答案 0 :(得分:16)

是的,在我看来,这将是一个更好的签名。

您是否尝试过明确指定比较类型?

Matchers.<ReadableInstant>greaterThan(new DateTime());

我不相信你可以使用静态导入来调用它,并且不幸地指定了类型参数 - 但这可能不会太困难。

当然,另一种方法是抛出论点:

greaterThan((ReadableInstant) new DateTime());

我没有Hamcrest方便,但上面使用你给我的签名测试类型对我来说很好。

答案 1 :(得分:2)

如果您经常使用它并且受到转换的困扰,您也可以像这样实现自己的匹配器:

public static Matcher<AbstractPartial> isAfter(final AbstractPartial partial) {
    return new BaseMatcher<AbstractPartial>(){

        @Override
        public void describeTo(final Description description) {
            description.appendText("after partial: ").appendValue(partial);
        }

        @Override
        public boolean matches(final Object object) {
            if (object instanceof AbstractPartial) {
                return ((LocalDate) object).isAfter(partial);
            }
            return false;
        }
    };
}

并按照以下方式进行测试:

    Set<LocalDate> dates = Sets.newHashSet(new LocalDate(2013, 1, 1), new LocalDate(2013, 1, 2), new LocalDate(
        2013, 1, 3));
    assertThat(
        CollectionUtils.isEqualCollection(filter(isAfter(new LocalDate(2013, 1, 1)), dates),
            Lists.newArrayList(new LocalDate(2013, 1, 2), new LocalDate(2013, 1, 3))), is(true));

如果您想使用DateTime而不是LocalDate,只需在第一个列表中用AbstractInstant替换AbstractPartial。