为了账号安全,请及时绑定邮箱和手机立即绑定

什么时候Java泛型要求<?扩展T>而不是<T>并且是否存在切换的缺点?

什么时候Java泛型要求<?扩展T>而不是<T>并且是否存在切换的缺点?

aluckdog 2019-07-25 18:49:40
什么时候Java泛型要求<?扩展T>而不是<T>并且是否存在切换的缺点?给出以下示例(使用带有Hamcrest匹配器的JUnit):Map<String, Class<? extends Serializable>> expected = null;Map<String, Class<java.util.Date>> result = null;assertThat(result, is(expected));这不能使用JUnit assertThat方法签名编译:public static <T> void assertThat(T actual, Matcher<T> matcher)编译器错误消息是: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>>>)但是,如果我将assertThat方法签名更改为:public static <T> void assertThat(T result, Matcher<? extends T> matcher)然后编译工作。所以有三个问题:为什么当前版本没有编译?虽然我模糊地理解这里的协方差问题,但如果必须的话,我当然无法解释它。将assertThat方法更改为Matcher<? extends T>?是否有任何缺点?如果你这样做,还有其他案例会破裂吗?assertThat在JUnit 中对方法进行泛化是否有任何意义?该Matcher级似乎并不需要它,因为JUnit的调用matches方法,它不与任何普通类型的,只是看起来像一个企图迫使一个类型安全这并不做任何事情,因为Matcher实际上只会不匹配,无论如何测试都会失败。不涉及不安全的操作(或似乎如此)。供参考,以下是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());     }}
查看完整描述

3 回答

  • 3 回答
  • 0 关注
  • 616 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信