从代码导入问题
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);
}
}