在forms参数类型中未声明的实际参数上调用方法

我是一名经验丰富的程序员,但他是一名Java初学者。 我有一个基准测试方法,它接受Map类型的参数并对其执行一些测试。 它可以在HashMap,Hashtable,IdentityHashMap,TreeMap等上调用,因为它们都实现了Map。 它们也都实现了Cloneable,但Eclipse告诉我不允许调用clone()方法。

private static double[] timeMapRemoves(Map map, Collection data, int reps) { Map map_clone = map.clone(); // OOPS -- "clone not accessible" 

所以我深入研究了Oracle网站,并提出了各种解决方案

 Map map_clone = null; Method clone = null; try { clone = map.getClass().getMethod("clone", null); map_clone = (Map)clone.invoke(map, null); } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } 

我觉得我可能像Drool Rockworm一样深入钻研并错过了规范的解决方案。

clone() protected ,这意味着它只能从子类或同一个包中访问。

重申评论:

这一切都取决于调用它的上下文,如果该上下文是相同的类型,那么您可以调用protected方法。 这里的上下文是一个不同的类型,因此无法调用它。

当您将参数更改为HashMap ,您可以调用它,因为HashMap使用public修饰符覆盖clone()方法。 简而言之:您不能通过简单的Map声明来做到这一点。

这意味着这样的情况会起作用:

 class X { public X(){ X newX = new X().clone(); } } 

但这不会:

 class X { public X(){ String newString = "hello".clone(); } } 

但话又说回来,这会:

 class X implements Map{ public X(){ Map map = new HashMap<>().clone(); } } 

这样:

 private static double[] timeMapRemoves(HashMap map, Collection data, int reps) { Map someMap = (Map) map.clone(); } 

注意我是如何将参数更改为HashMap

为什么这样做的原因很简单: HashMap定义了自己的clone()方法。

 public Object clone() { HashMap result = null; try { result = (HashMap)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; }