抱歉,我的头衔可能会产生误导。
这实际上来自我最近的一次JAVA采访,面试官问我这个问题:如果我们有一个HashMap类型的参数,我们怎样才能确保在接受方法中,用户无法做到修改这个HashMap(即get()方法)
我在面试中使用决赛,面试官根本没有欣赏,我在网上搜索这个话题已经有一段时间了但仍然没有任何线索。
专家能帮忙吗?感谢
答案 0 :(得分:1)
听起来你可能来自C ++背景,其中制作参数const
确实会阻止方法修改对象。在Java中,final
仅阻止分配给该变量;你仍然可以调用修改对象本身的方法。
所以,例如:
void callingMethod() {
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
map.put(1, 2);
badMethod(map);
// NullPointerException
System.out.println(map.get(1).intValue());
}
void badMethod(final HashMap<Integer, Integer> map) {
map.clear();
}
有几种方法可以防止这种情况:
答案 1 :(得分:1)
使用final
并不妨碍在引用上调用方法。它只会使引用本身不可更改。所以你的回答是错误的。
我的建议是使用通用(仅用于此类访谈,而不是程序!):
Map<String, String> map = new HashMap< String, String >();
map.put("a", "b"); // OK
Map< ? extends String, ? extends String > mapRO = new HashMap< String, String >();
mapRO.put("a", "b"); // Compile error
String value = mapRO.get("a"); // OK
正如您所看到的,使用? extends ...
隐藏泛型类型可以防止“写入”方法(如put
)被调用,因为它们通常需要完全定义类型。但是你仍然可以调用clear()
,所以这是游泳池安全概念。
此外,您可以使用一些包装器,这会在所有“写入”方法调用上抛出异常。
答案 2 :(得分:0)
如何从像here?
这样的Hashmap创建不可修改的Collection然后你会这样做:
yourMethod(Collections.unmodifiableMap(yourHashmap));
仅使用final意味着您无法覆盖该引用与此块中的其他引用,它不会阻止该对象上的任何方法调用。
答案 3 :(得分:0)
我认为这是不可改变的或不可修改的地图。
Collections#unmodifiableCollection
它返回指定地图的不可修改的视图。这种方法 允许模块为用户提供对内部的“只读”访问 地图。对返回的地图上的查询操作“通读”到 指定地图,并尝试修改返回的地图,是否直接 或通过其集合视图,产生一个 UnsupportedOperationException异常。
答案 4 :(得分:0)
答案 5 :(得分:0)
Collections.unmodifiableMap(myMap)
将返回只读地图。您应该处理由此返回的Map对象。
答案 6 :(得分:0)
有两种方式
1)this.map = Collections.unmodifiableMap(map);
2)防御性复制:this.map = new HashMap(map);