java方法调用提示作用域受限
在学习 Object类的 clone() 方法时,发现怎么都调用不了,于是对作用域的作用产生了疑问,深入理解了一下,发现是自己错了.
错误代码
public class B { @Test public void test() { A a = new A(); a.clone(); // 编译报错,提示clone()的作用域为protect,当前类中访问不了 } }
当时的理解是 A类是 Object类的子类,为什么调用不了父类 Object中 protected 修饰的 clone() 方法.
这边有两个错误需要指出来,一个是调用方式错误, 一个是对 protected的作用范围有混淆.
调用错误
假设 A 类中有静态方法 m1()和非静态方法 m2(),那么不同作用域的调用如下:
表1
图1
所以上面错误代码中的第5行 a.clone() 的调用方式适用于同一包下或者所有类中的调用,又 B 类和 Object 类不属于同一包下,所以 a.clone()想成功调用的话, 只能将 clone() 方法的作用域改为 public.
protected的作用域理解错误
方法作用域的范围分为当前类中,同一包中,子类中,所有类中,所有的类都能规划到这4种范围当中. 和调用某个对象的方法(a.clone())没有关系,不要混淆.
在 B 类中想调用 Object 类中的 clone()方法, B 类要么和 Object类同一包下,要么是它的子类,实际上 B类只能是 Object类的子类,根据表1,调用方式为 clone();
在 B 类中想调用 A类的 clone() 方法, 不行,除非 A类重写 clone()方法,并且 clone()方法的作用域需要考虑清楚.
正确调用
所以正确打开方式如下: B 类调用 Object 类中的 clone() 方法
public class B { @Test public void test() { clone(); } }
B 类调用 A 类中的 clone() 方法
public class B { @Test public void test() { A a = new A(); a.clone(); } } public class A { @Override public Object clone() { return clone(); } }
总结
对于一个方法的调用,如果提示作用域受限,需要一步步地去排查原因,主要还是作用域的概念要清晰,不能稀里糊涂的,因为这个坑今天不填,明天还是要填,不可避免.