2012-12-29 48 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)