2012-12-29 55 views

回答

5

两者。如果你尝试编译它试图访问不可访问的对象或方法的代码,你会得到编译时错误:

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 
+0

所以,访问信息确实存储在类文件中? – corazza

+0

Yeap。例如,请参阅field_info结构:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.5 – tcb

2

它在编译时检查。我试过以下两类:

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 

但是,请记住,这简单的例子只适用于基本情况。当考虑反射时,这种行为可能会改变,即变量的名称只在运行时确定。在这种情况下,不可能在编译时检查访问修饰符,并且检查将不得不推迟到运行时。

+0

尽管所有这些反射方法,'getField()','getMethod()',等等。强迫你处理这种可能性,因为他们抛出检查异常。 – ApproachingDarknessFish

2

在这两种情况下。在编译时很容易看到。但在运行时也不难测试。创建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)