Possible Duplicate:
JVM/Java, are method accessibility rules enforced at runtime?在编译时或运行时检查访问权限吗?
当使用具有公共和私有字段和成员的一类,是检查访问冲突(例如,试图从外部类访问私有域)在编译时或运行时的代码?或两者?
Possible Duplicate:
JVM/Java, are method accessibility rules enforced at runtime?在编译时或运行时检查访问权限吗?
当使用具有公共和私有字段和成员的一类,是检查访问冲突(例如,试图从外部类访问私有域)在编译时或运行时的代码?或两者?
两者。如果你尝试编译它试图访问不可访问的对象或方法的代码,你会得到编译时错误:
field has private access in package.Class
而且,当你的类尝试在运行时访问某些领域,JVM检查访问:
Exception in thread "main" java.lang.IllegalAccessError: tried to access field package.Class.field from class YourClass
它在编译时检查。我试过以下两类:
class A {
private int i;
}
和
class B {
private void test() {
A a = new A();
a.i = 5;
}
}
当我尝试编译B.java
,出现以下错误:
B.java:4: i has private access in A
a.i = 5;
^
1 error
但是,请记住,这简单的例子只适用于基本情况。当考虑反射时,这种行为可能会改变,即变量的名称只在运行时确定。在这种情况下,不可能在编译时检查访问修饰符,并且检查将不得不推迟到运行时。
尽管所有这些反射方法,'getField()','getMethod()',等等。强迫你处理这种可能性,因为他们抛出检查异常。 – ApproachingDarknessFish
在这两种情况下。在编译时很容易看到。但在运行时也不难测试。创建2个班
public class Test1 {
public static void main(String[] args) throws Exception {
Test2.hello();
}
}
public class Test2 {
static void hello() {
System.out.println("hello");
}
}
编译和运行java Test1
,它的工作原理确定
现在改变的Test2作为
priivate static void hello() {
System.out.println("hello");
}
,并分别对其进行编译,使Test1.class不变。运行java Test1
。你会得到
Exception in thread "main" java.lang.IllegalAccessError: tried to access method Test2.hello()V from class Test1
at Test1.main(Test1.java:5)
所以,访问信息确实存储在类文件中? – corazza
Yeap。例如,请参阅field_info结构:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.5 – tcb