java中如何创建不可变并且static的静态集合

以map为例

findbug错误提示:

MS_MUTABLE_COLLECTION_PKGPROTECT, Priority: Normal
XX.XX.XXX.XX is a mutable collection which should be package protected
A mutable collection instance is assigned to a final static field, thus can be changed by malicious code or by accident from another package. The field could be made package protected to avoid this vulnerability. Alternatively you may wrap this field into Collections.unmodifiableSet/List/Map/etc. to avoid this vulnerability.

错误案例:

public class TestMap {
  private static final Map<Integer,String> map = new LinkedHashMap<Integer, String>();
  static {
    map = new HashMap();
    map.put(1, "one");
    map.put(2, "two");
  }
}

正确的做法 (通过Collections.unmodifiableMap)

public class TestMap {
  private static final Map<Integer,String> map ;
  static {
    Map<Integer,String> tempMap  = new HashMap();
    tempMap.put(1, "one");
    tempMap.put(2, "two");
    map = Collections.unmodifiableMap(tempMap);
  }
}

如果现在往map里添加元素,则抛出UnsupportedOperationException异常

一下附上一段源码

/**
         * We need this class in addition to UnmodifiableSet as
         * Map.Entries themselves permit modification of the backing Map
         * via their setValue operation.  This class is subtle: there are
         * many possible attacks that must be thwarted.
         *
         * @serial include
         */
        static class UnmodifiableEntrySet<K,V>
            extends UnmodifiableSet<Map.Entry<K,V>> {
            private static final long serialVersionUID = 7854390611657943733L;

            @SuppressWarnings({"unchecked", "rawtypes"})
            UnmodifiableEntrySet(Set<? extends Map.Entry<? extends K, ? extends V>> s) {
                // Need to cast to raw in order to work around a limitation in the type system
                super((Set)s);
            }

            static <K, V> Consumer<Map.Entry<K, V>> entryConsumer(Consumer<? super Entry<K, V>> action) {
                return e -> action.accept(new UnmodifiableEntry<>(e));
            }

            public void forEach(Consumer<? super Entry<K, V>> action) {
                Objects.requireNonNull(action);
                c.forEach(entryConsumer(action));
            }

            static final class UnmodifiableEntrySetSpliterator<K, V>
                    implements Spliterator<Entry<K,V>> {
                final Spliterator<Map.Entry<K, V>> s;

                UnmodifiableEntrySetSpliterator(Spliterator<Entry<K, V>> s) {
                    this.s = s;
                }

                @Override
                public boolean tryAdvance(Consumer<? super Entry<K, V>> action) {
                    Objects.requireNonNull(action);
                    return s.tryAdvance(entryConsumer(action));
                }

                @Override
                public void forEachRemaining(Consumer<? super Entry<K, V>> action) {
                    Objects.requireNonNull(action);
                    s.forEachRemaining(entryConsumer(action));
                }

                @Override
                public Spliterator<Entry<K, V>> trySplit() {
                    Spliterator<Entry<K, V>> split = s.trySplit();
                    return split == null
                           ? null
                           : new UnmodifiableEntrySetSpliterator<>(split);
                }
				..................
				

转载于:https://my.oschina.net/MjShao/blog/2872388

### Java 静态集合中的删除操作 在Java中,静态集合通常指的是通过`Collections.unmodifiable*`方法创建不可变集合。这些集合不允许任何结构上的修改,这意味着一旦创建就不能再添加、移除或更改其中的元素。 对于尝试对静态集合执行删除操作的情况,会抛出`UnsupportedOperationException`异常[^1]。下面是一个简单的例子展示这一点: ```java import java.util.*; public class StaticCollectionExample { public static void main(String[] args) { List<Integer> originalList = new ArrayList<>(Arrays.asList(1, 2, 3)); // 创建一个只读视图 List<Integer> unmodifiableList = Collections.unmodifiableList(originalList); try { unmodifiableList.remove(Integer.valueOf(2)); // 尝试删除元素 } catch (UnsupportedOperationException e) { System.out.println("无法修改静态集合:" + e.getMessage()); } } } ``` 此代码片段展示了试图从由`Collections.unmodifiableList()`返回的对象中删除元素的行为。这将触发`UnsupportedOperationException`,表明该类型的集合不支持此类变更操作。 值得注意的是,虽然不能直接修改静态集合本身的内容,但如果原始列表发生变化,则这种变化不会反映在已经转换成静态版本后的副本上;反之亦然——即静态集合内部的变化也不会影响到其背后的实际数据源。 为了安全地进行增删改查的操作,应该先解除对该集合的保护状态(如果有),或者基于原集合作一个新的可变实例来进行必要的更新后再重新封装为静态形式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值