0

我在运行 java 1.6.0_22-b04 sun 和 tomcat 6.0.32 的 2 个不同服务器上安装了一个 java 应用程序

登台服务器让我头疼,出现以下错误:

java.lang.UnsupportedOperationException : null
   java.util.AbstractMap$SimpleImmutableEntry.setValue (AbstractMap.java:726)

这是引发此异常的代码

for (Entry<Integer, BigDecimal> entry : map.entrySet()) {
  entry.setValue(new BigDecimal("999"));
}

我只是在这台服务器上遇到这个问题。本地和其他服务器上的一切都很好,代码相同。

我在谷歌上发现了很多关于这个异常的结果,但它们都与哈德森有关。

4

3 回答 3

4

正如在引发异常的评论服务器中提到的那样,已使用-XX:+AggressiveOpts选项启动。
JDK-7006877解释了为什么-XX:+AggressiveOpts会改变TreeMap行为。

在 1.6.0_14 中添加了 TreeMap 的实验性实现:
http

://www.oracle.com/technetwork/java/javase/6u14-137039.html#performance-6u14这个新实现通过命令行选项 -XX 启用: +积极的选择。

使用标准的 TreeMap 实现,可以通过调用 Map.Entry.setValue() 来修改 TreeMap 的 Iterator 返回的 Map.Entry 键/值对的值。

启用实验实现后,无法以这种方式修改值。调用 Map.Entry.setValue() 会导致 UnsupportedOperationException。

于 2016-05-06T14:17:20.480 回答
2

你能提供一个失败的简单例子吗?

TreeMap<Integer, BigDecimal> map = new TreeMap<>();
map.put(0, BigDecimal.ZERO);
map.put(1, BigDecimal.ONE);

for (Map.Entry<Integer, BigDecimal> entry : map.entrySet()) {
    entry.setValue(new BigDecimal("999"));
}
System.out.println(map);

印刷

{0=999, 1=999}

Java 6 中的 TreeMap 将为单独的条目提供异常

map.floorEntry(1).setValue(BigDecimal.TEN); // fails.

根据消息来源,只有 ConcurrentSkipListMap 使用这个类。

Map<Integer, BigDecimal> map = new ConcurrentSkipListMap<>();

总是给我

Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractMap$SimpleImmutableEntry.setValue(AbstractMap.java:759)

顺便说一句:我在 Java 6 和 7 中得到了相同的行为。

于 2012-08-29T15:56:00.830 回答
1

来自Java 6 中的TreeMapJavadoc :

Map.Entry此类中的方法及其视图返回的所有对表示映射在它们生成时的快照。他们支持该Entry.setValue方法。(但请注意,可以使用 put 更改关联映射中的映射。)

那么——你为什么会感到惊讶呢?

于 2012-08-29T16:58:58.183 回答