java 泛型缺点_Java泛型何时需要<?扩展了T>而不是<T>,切换是否有不利之处?

本文讨论了在使用JUnit断言时遇到的编译问题,涉及泛型和方法签名的匹配。作者指出,当尝试将`Map<String, String>`类型的预期值与结果值进行断言时,原始的`assertThat`方法签名不匹配,导致编译错误。通过修改方法签名以允许协变,编译问题得到解决。然而,这引入了潜在的类型安全性问题。文章探讨了这种方法的优缺点,以及JUnit中泛型断言方法的意义,强调了类型安全在测试中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定以下示例(将JUnit与Hamcrest匹配器结合使用):

Map> expected = null;

Map> result = null;

assertThat(result, is(expected));

这不能与以下内容的JUnit assertThat方法签名一起编译:

public static void assertThat(T actual, Matcher matcher)

编译器错误消息是:

Error:Error:line (102)cannot find symbol method

assertThat(java.util.Map>,

org.hamcrest.Matcher

extends java.io.Serializable>>>)

但是,如果我将assertThat方法签名更改为:

public static void assertThat(T result, Matcher extends T> matcher)

然后编译工作。

所以三个问题:

为什么当前版本完全不编译?尽管我在这里模糊地理解了协方差问题,但如果需要的话,我当然无法解释。

将assertThat方法更改为有什么缺点Matcher extends T>吗?如果这样做,还有其他情况会中断吗?

assertThat在JUnit中通用化方法有什么意义吗?该Matcher级似乎并不需要它,因为JUnit的调用matches方法,它不与任何通用的,只是看起来像键入企图迫使一个类型安全这并不做任何事情,因为Matcher只会事实上并不匹配,则无论如何测试都将失败。不涉及任何不安全的操作(或看起来如此)。

供参考,以下是JUnit的实现assertThat:

public static void assertThat(T actual, Matcher matcher) {

assertThat("", actual, matcher);

}

public static void assertThat(String reason, T actual, Matcher 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());

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值