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