【问题标题】:How can it be, that ConcurrentHashMap has no keySet() method? [duplicate]ConcurrentHashMap 怎么可能没有 keySet() 方法? [复制]
【发布时间】:2017-12-15 16:46:24
【问题描述】:

我正在调试Java 代码,从Matlab 调用并得到一个异常:

Java exception occurred:
java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView;

怎么可能,那个库类没有库方法?

更新

Matlab 正在使用Java7。我调用的代码是为Java8 编译的,包含语法

for (Tag t : matrix.keySet()) {

Java8-特定。虽然声称它应该与Java7 二进制兼容,否则在Java8 中做许多妥协是没有意义的。

【问题讨论】:

  • 您运行的是什么版本的 Java?乍一看,Matlab 期待的是 Java 8 版本,但您可能正在运行 7。
  • @Raz_Muh_Taz true,但在 Java 7 中,keySet 根据其签名返回 Set<K>,而在 Java 8 中,它返回 ConcurrentHashMap.KeySetView<K,V>
  • @Dmis 您可以在Java8 机器中使用Java7 代码,但不能在Java7 机器中使用Java8 代码。 stackoverflow.com/questions/4692626/…
  • @Dims 是什么让您期望您可以使用针对 Java 8 编译的代码,并期望 Java 8 中存在的所有方法都存在于 Java 1.0 中?这不是兼容进化的运作方式。您可以安全地及时向前 - 非常小心以确保这是真的 - 但不能向后
  • 看我的回答here

标签: java matlab java-8 java-7 nosuchmethoderror


【解决方案1】:

在 Java 8 中,ConcurrentHashMap.keySet() 返回类型已更改。 在 Oracle JDK 7 中:

public Set<K> keySet() {
    Set<K> ks = keySet;
    return (ks != null) ? ks : (keySet = new KeySet());
}

在 Oracle JDK 8 中:

public KeySetView<K,V> keySet() {
    KeySetView<K,V> ks;
    return (ks = keySet) != null ? ks : (keySet = new KeySetView<K,V>(this, null));
}

public static class KeySetView<K,V> extends CollectionView<K,V,K>
    implements Set<K>, java.io.Serializable {

【讨论】:

  • 那么,Java 不能从1.7 移植到1.8
  • @Dims 这是一个完美兼容的更改。 KeySetView&lt;K,V&gt; 扩展(是-a)Set&lt;K&gt;。这使得在ConcurrentHashMap 中实现keySet() 成为MapkeySet()协变覆盖。从返回 Set&lt;K&gt; 到更精致的 KeySetView&lt;K,V&gt; 的变化是二进制和源代码兼容的变化。针对 7 个库编写或编译的代码仍可在 8 个库上运行。
  • @BrianGoetz 如果它不起作用,它有什么酷炫和兼容性?使用“协变覆盖”或任何其他东西是没有意义的。他们可以完全重命名方法并完全改变参数和结果类型:效果是一样的——不起作用。
  • 看我的回答here
  • 我发现即使你写了Set&lt;Chunk&gt; chunks = wrap.chunksAddPlayer.keySet();(注意代码兼容Java 7),用Java 8编译,编译的时候还是会转换成KeySetView,也就是说你将无法在 Java 7 中使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
  • 2018-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多