【问题标题】:Hamcrest assertThat - type inferenceHamcrest assertThat - 类型推断
【发布时间】:2016-01-07 20:35:13
【问题描述】:

这是我在一个项目中所做工作的简化版本:

List<String> names = ...
assertThat(names, is(empty()));

这在我在 Java 1.7.0.79(和 1.6.0.31)上运行的 Eclipse 上运行良好。

但是,在使用 Java 1.7.0.55(和 1.6.0.29)的远程系统上编译失败,错误消息如下:

no suitable method found for assertThat(java.util.List<String>,org.hamcrest.Matcher<java.util.Collection<java.lang.Object>>)
    method org.hamcrest.MatcherAssert.<T>assertThat(T,org.hamcrest.Matcher<? super T>) is not applicable
      (actual argument org.hamcrest.Matcher<java.util.Collection<java.lang.Object>> cannot be converted to org.hamcrest.Matcher<? super java.util.List<String>> by method invocation conversion)
    method org.hamcrest.MatcherAssert.<T>assertThat(java.lang.String,T,org.hamcrest.Matcher<? super T>) is not applicable
      (cannot instantiate from arguments because actual and formal argument lists differ in length)
    method org.hamcrest.MatcherAssert.assertThat(java.lang.String,boolean) is not applicable
      (actual argument java.util.List<String> cannot be converted to java.lang.String by method invocation conversion)

我希望第一个重载的变体与我的情况相匹配,但这并不是由于看似不确定的类型推断。为什么编译器知道isempty 方法的signatures 显然应该是org.hamcrest.Matcher&lt;java.util.Collection&lt;? extends java.lang.Object&gt;&gt;,却认为实际参数是org.hamcrest.Matcher&lt;java.util.Collection&lt;java.lang.Object&gt;&gt; 类型。

问题是我对可以在远程系统上切换到什么 JDK 的控制有限,这是一种刺激。测试代码,我也不允许解决这个问题。 所以,目前我要做的只是了解问题是否是由于上述 JDK 上的错误类型推断造成的。 诚然,我没有在上述 JDK 上尝试过同样的事情在我的个人电脑上。

我使用 hamcrest 1.3 BTW。

【问题讨论】:

  • 提供明确的类型参数。
  • Eclipse 使用 JDK 编译器,它使用自己的编译器,因此使用运行 1.7.0.79 的 Eclipse 编译与使用 JDK @987654335 中的 javac 编译不同@。 Eclipse 编译器可能有更好的推理逻辑。
  • @SotiriosDelimanolis 显然。我现在无法更改代码 - 我只是想了解这里出了什么问题。
  • @Andreas 是的。我使用 jdks 1.7.0.79(和 1.6.0.31)构建的 maven 运行良好,所以这不仅仅是 Eclipse 使用更智能的编译器的情况。

标签: java generics hamcrest


【解决方案1】:

在失败的系统上构建时似乎使用了 Hamcrest 1.2。当我使用 Hamcrest 1.2 构建您的代码时,它在使用 1.3 时失败并显示相同的错误消息。检查 Hamcrest 代码,Matchers.empty() 签名在 1.3 中已更改为:

public static <E> org.hamcrest.Matcher<java.util.Collection<E>> empty() // 1.2

public static <E> org.hamcrest.Matcher<java.util.Collection<? extends E>> empty() // 1.3

这将解释为什么它在 1.2 上失败但在 1.3 上有效。

您应该检查您的项目设置和系统设置,以确保在构建时只有 hamcrest 1.3 在类路径上。

【讨论】:

  • 啊,也许我的错。我和你有同样的怀疑,我检查了GitHub 中的代码,Hamcrest-library 下缺少该类,所以我认为它是在 1.3 中添加的。您能指出显示此方法签名的 1.2 源代码/javadoc 吗?
  • @mystarrocks 在此处检查例如 GrepCode:grepcode.com/file/repo1.maven.org/maven2/org.hamcrest/…
  • 谢谢 - 我有点懒,没有注意到这一点。我希望类路径中的多个 lib 版本也会成为问题,尽管我还无法确认。
  • 糟糕 - hamcrest-all:jar:1.3 似乎依赖于 hamcrest-library:jar:1.2.1。 o_O
  • @mystarrocks 听起来很奇怪。我从Maven Central下载的hamcrest-all:jar:1.3的版本根本没有任何依赖。
猜你喜欢
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多