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

作用域 private default protected public 可见性 当前类 同一包下 子类 所有类 静态方法 m1(); A.m1(); m1(); A.m1(); 非静态方法 m2(); new A().m2(); m2(); new A().m2();

图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();
    }
}

总结

对于一个方法的调用,如果提示作用域受限,需要一步步地去排查原因,主要还是作用域的概念要清晰,不能稀里糊涂的,因为这个坑今天不填,明天还是要填,不可避免.

经验分享 程序员 微信小程序 职场和发展