gpt4 book ai didi

java - 泛型 hell : hamcrest matcher as a method parameter

转载 作者:太空狗 更新时间:2023-10-29 22:41:31 24 4
gpt4 key购买 nike

所以,让我们有一个字符串列表和一个接受 Hamcrest 匹配器并返回 matches() 的结果的函数。提供的匹配器的方法:

public boolean matchIt(final Matcher<? super List<String>> matcher) {
final List<String> lst = obtainListFromSomewhere();
return matcher.matches(lst);
}

到目前为止一切顺利。现在我可以轻松调用:

matchIt(empty());
matchIt(anything());
matchIt(hasItem("item"));
matchIt(everyItem(equalToIgnoringCase("item")));

...因为所有这些工厂静态方法都会生成一个匹配方法签名的匹配器 Matcher<? super List<String>> .

但是,我认为接受 Iterable 对象的匹配器应该被 matchIt() 接受。方法也是:

matchIt(everyItem(anything()));

所以我天真地改变了matchIt()方法签名:

public boolean matchIt(final Matcher<? super List<? super String>> matcher);

但它根本不起作用。它不仅不接受 everyItem(anything()) , 它甚至不接受以前正确的 everyItem(equalToIgnoringCase("item"))说(1.7.0_05编译器版本):

actual argument Matcher<Iterable<String>> cannot be converted to Matcher<? super List<? super String>> by method invocation conversion

什么?那么这里出了什么问题?是matchIt()吗方法签名或者是 everyItem() Hamcrest 签名设计错误?还是只是 Java 泛型系统无法修复?非常感谢您的评论!

编辑@rlegendi 我的目的是为客户端提供一个接口(interface)来添加和执行关于列表的谓词。那是 matchIt()方法。打电话matchIt(anything())在这种情况下有意义,客户想知道列表是否是任何东西。打电话matchIt(empty())表示客户端想知道列表是否为空。 matchIt(everyItem(equalToIgnoringCase("item"))) 反之亦然和 matchIt(hasItem("item")) .

我的目标是获得最好的 matchIt()方法签名可能。 Matcher<? super List<String>>适用于所有先前的场景。但是,我认为应该允许客户添加 Matcher<Iterable<Object>>匹配器(例如 matchIt(everyItem(notNullValue()) 在这里很有意义,客户想知道列表中的每个字符串项是否不为空)。

但是我找不到合适的签名,matchIt(Matcher<? super List<? super String>>)不适用于 everyItem(notNullValue());

我使用 Hamcrest 1.3。

编辑 2:

我相信我已经找到了我的根本误解。

everyItem(anything())表达式返回 Matcher<Iterable<Object>> 类型的对象.所以我可以轻松做到Matcher<Iterable<Object>> m = everyItem(anything());

但是我不明白的是为什么我做不到Matcher<? super List<? super String>> m1 = m; .似乎Matcher<Iterable<Object>>不是 Matcher<? super List<? super String>>但我不明白为什么。

我什至做不到Matcher<? super List<?>> m1 = m; . Matcher<Iterable<Object>>不是 Matcher<? super List<?>> ?为什么?

最佳答案

However, I believe a matcher that accepts an Iterable of objects should be accepted by the matchIt() method as well

不,那是不正确的。而不是 Iterable ,让我们考虑 List目前。所以你有一个 Matcher<List<Object>> , 及其 matches方法需要一个 List<Object> .现在,这需要 List<String> 吗? ?不,您可能已经知道原因了——因为它可以添加类型为 Object 的对象进入列表。

现在,我知道在命名类时 Matcher , 你期待 matches方法是只读的,并且不改变给它的列表。但是,不能保证这一点。如果它确实没有向列表中添加任何内容,则匹配器的正确类型将是 Matcher<List<?>> , 其中 (1) 不允许 matches添加任何东西到列表的方法,除了null , (2) 将允许 matches获取任何类型列表的方法。

我相信您当前的方法签名 public boolean matchIt(final Matcher<? super List<String>> matcher)已经允许 Matcher<List<?>> (或 Matcher<Iterable<?>> )。

关于java - 泛型 hell : hamcrest matcher as a method parameter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13000767/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com