在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; }