为什么 Collections.unmodifiableMap 不检查传递的地图是否已经是 UnmodifiableMap?

Adw*_*mar 6 java performance

查看java.util.Collections.unmodifiableMap实现(OpenJDK 11):

    /**
     * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
     * specified map. Query operations on the returned map "read through"
     * to the specified map, and attempts to modify the returned
     * map, whether direct or via its collection views, result in an
     * {@code UnsupportedOperationException}.<p>
     *
     * The returned map will be serializable if the specified map
     * is serializable.
     *
     * @param <K> the class of the map keys
     * @param <V> the class of the map values
     * @param  m the map for which an unmodifiable view is to be returned.
     * @return an unmodifiable view of the specified map.
     */
    public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) {
        return new UnmodifiableMap<>(m);
    }
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么实现不检查传递的地图可能已经是一个 UnmodifiableMap,像这样:

    public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) {
        if(m instanceof UnmodifiableMap){
            return m;
        }
        return new UnmodifiableMap<>(m);
    }
Run Code Online (Sandbox Code Playgroud)

相反,这个问题可以扩展到所有其他不可修改的集合,一个简单的检查有助于避免不需要的计算器溢出错误以及不必要的包装。

我想知道是否有理由不这样做?

此外,由用户UnmodifiableMap进行私人检查也是不可能的(不使用反射/类加载器魔法)。

Eug*_*ene 3

我总是认为这也有点奇怪,事实上,当您使用 Java 9 或更高版本执行几乎相同的逻辑操作时,通过:

    Map<String, Integer> left = Map.of("one", 1);
    Map<String, Integer> right = Map.copyOf(left);
    System.out.println(left == right); // true
Run Code Online (Sandbox Code Playgroud)

您可以看到该实现会进行检查以查看是否Map已知它是不可变的:

static <K, V> Map<K, V> copyOf(Map<? extends K, ? extends V> map) {
    if (map instanceof ImmutableCollections.AbstractImmutableMap) {
        return (Map<K,V>)map;
    } else {
        return (Map<K,V>)Map.ofEntries(map.entrySet().toArray(new Entry[0]));
    }
}
Run Code Online (Sandbox Code Playgroud)