Java函数作用域的原理

从代码导入问题

class testParent

package cm.xxx.test.inherit;

public class TestParent {
	private void doTest() {
		System.out.println("in TestParent::doTest()");
	}
	
	public static void main(String[] args) {
		TestParent tp = new TestParent();
		tp.doTest(); // compile success
	}
}

class TestMain

package com.xxx.test.main;

import com.xxx.test.inherit.TestParent;

public class TestMain {

	public static void main(String[] args) {
		TestParent tp = new TestParent();
		tp.doTest();  // compile failure
	}
}

看两个类:

对于TestMain里面的编译错误很好理解,因为tp.doTest()是定义成private的,所以不能访问。

对于TestParent里面的代码,有些爱思考的程序员就会有疑问,也应该报错啊,调用的tp.doTest(),而doTest()是一个private成员函数呀。

这里面一个主要的问题是,对于类TestParent的代码而言,不管怎么用,它都是在类TestParent里面的代码,虽然创建了一个实例TestParent,但是创建这个实例的代码,以及调用实例成员doTest()的代码都在TestParent类本身里面。说起来很拗口,一句话尽管doTest()是private的,但对于类本身而言都是可见的。

(我只能说java就是这么设计的,虽然个人对这个设计持有怀疑态度,C++也是这么设计的)


从另一角度来思考问题,限定作用域只对编译器发生作用,对于编译后的指令码而言只有地址的概念,并不存在严格意义上的private/protected/public之分,上述例子中doTest()对于编译器而言它是可知的,在同一个类里面。而对于编译后的二进制代码指令private/protected/private已经失去了意义,比如我们可以使用java反射机制很容易的调用一个private函数。

package com.xxx.test.main;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.xxx.test.inherit.TestParent;

public class TestMain {

	public void run() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		TestParent tp = new TestParent();
		
		Class<?> clazz = tp.getClass();
		Method method = clazz.getDeclaredMethod("doTest");
		method.setAccessible(true);
		method.invoke(tp);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值