我是一名经验丰富的程序员,但他是一名Java初学者。我有一个基准测试方法,它接受Map类型的参数并对其执行一些测试。它可以在HashMap,Hashtable,IdentityHashMap,TreeMap等上调用,因为它们都实现了Map。它们也都实现了Cloneable,但Eclipse告诉我不允许调用clone()方法。
private static double[] timeMapRemoves(Map<String,Integer> map,
Collection<String> data,
int reps) {
Map<String,Integer> map_clone = map.clone(); // OOPS -- "clone not accessible"
所以我深入研究了Oracle网站,并提出了各种解决方案
Map<String,Integer> map_clone = null;
Method clone = null;
try {
clone = map.getClass().getMethod("clone", null);
map_clone = (Map<String,Integer>)clone.invoke(map, null);
} catch (NoSuchMethodException | SecurityException
| IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
e.printStackTrace();
}
我觉得我可能像Drool Rockworm一样深入研究并错过了规范的解决方案。
答案 0 :(得分:1)
clone()
是protected
,这意味着它只能从子类或同一个包中访问。
重申评论:
这一切都取决于调用它的上下文,如果该上下文是相同的类型,则可以调用protected
方法。这里的上下文是一个不同的类型,因此无法调用它。
例如,当您将参数更改为HashMap<K, V>
时,您可以调用它,因为HashMap会使用公共修饰符覆盖clone()
方法。简而言之:您不能通过简单的Map<K, V>
声明来做到这一点。
这意味着这样的情况会起作用:
class X {
public X(){
X newX = new X().clone();
}
}
但这不会:
class X {
public X(){
String newString = "hello".clone();
}
}
但话又说回来:
class X implements Map<String, String>{
public X(){
Map<String, String> map = new HashMap<>().clone();
}
}
这样:
private static double[] timeMapRemoves(HashMap<String,Integer> map,
Collection<String> data,
int reps) {
Map<String, String> someMap = (Map<String, String>) map.clone();
}
注意我是如何将参数更改为HashMap<String,Integer>
。
为什么这样做的原因非常简单:HashMap
定义了自己的clone()
方法。
public Object clone() {
HashMap<K,V> result = null;
try {
result = (HashMap<K,V>)super.clone();
} catch (CloneNotSupportedException e) {
// assert false;
}
result.table = new Entry[table.length];
result.entrySet = null;
result.modCount = 0;
result.size = 0;
result.init();
result.putAllForCreate(this);
return result;
}