本文共 2390 字,大约阅读时间需要 7 分钟。
为什么80%的码农都做不了架构师?>>>
以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 Mapmap = new LinkedHashMap();
static {
map = new HashMap();
map.put(1, "one");
map.put(2, "two");
}
}
正确的做法 (通过Collections.unmodifiableMap)
public class TestMap {
private static final Mapmap ;
static {
MaptempMap = 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 UnmodifiableEntrySetextends UnmodifiableSet> {
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 Consumer> entryConsumer(Consumer super Entry> action) {
return e -> action.accept(new UnmodifiableEntry<>(e));
}
public void forEach(Consumer super Entry> action) {
Objects.requireNonNull(action);
c.forEach(entryConsumer(action));
}
static final class UnmodifiableEntrySetSpliteratorimplements Spliterator> {
final Spliterator> s;
UnmodifiableEntrySetSpliterator(Spliterator> s) {
this.s = s;
}
@Override
public boolean tryAdvance(Consumer super Entry> action) {
Objects.requireNonNull(action);
return s.tryAdvance(entryConsumer(action));
}
@Override
public void forEachRemaining(Consumer super Entry> action) {
Objects.requireNonNull(action);
s.forEachRemaining(entryConsumer(action));
}
@Override
public Spliterator> trySplit() {
Spliterator> split = s.trySplit();
return split == null
? null
: new UnmodifiableEntrySetSpliterator<>(split);
}
..................
转载地址:http://ifevo.baihongyu.com/