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

为什么80%的码农都做不了架构师?>>>   hot3.png

以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 map = new LinkedHashMap();
  static {
    map = new HashMap();
    map.put(1, "one");
    map.put(2, "two");
  }
}

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

public class TestMap {
  private static final Map map ;
  static {
    Map 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
            extends UnmodifiableSet> {
            private static final long serialVersionUID = 7854390611657943733L;

            @SuppressWarnings({"unchecked", "rawtypes"})
            UnmodifiableEntrySet(Set> s) {
                // Need to cast to raw in order to work around a limitation in the type system
                super((Set)s);
            }

            static  Consumer> entryConsumer(Consumer> action) {
                return e -> action.accept(new UnmodifiableEntry<>(e));
            }

            public void forEach(Consumer> action) {
                Objects.requireNonNull(action);
                c.forEach(entryConsumer(action));
            }

            static final class UnmodifiableEntrySetSpliterator
                    implements Spliterator> {
                final Spliterator> s;

                UnmodifiableEntrySetSpliterator(Spliterator> s) {
                    this.s = s;
                }

                @Override
                public boolean tryAdvance(Consumer> action) {
                    Objects.requireNonNull(action);
                    return s.tryAdvance(entryConsumer(action));
                }

                @Override
                public void forEachRemaining(Consumer> action) {
                    Objects.requireNonNull(action);
                    s.forEachRemaining(entryConsumer(action));
                }

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

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

你可能感兴趣的:(java中如何创建不可变并且static的静态集合)