1. 程式人生 > >Java內部類和外部類互相訪問問題

Java內部類和外部類互相訪問問題

今天在分析android的AMS的時候,發現在AMS中出現了內部類訪問外部類私有方法的操作,一時之間覺得有些奇怪:為毛private的方法可以被訪問??之前的認識是private方法是不可以通過物件方式呼叫的,但是現在的程式碼確實這麼做了!!為什麼呢?
帶著這個問題,我google了一下,最終找到了這個stackoverflow的帖子:
http://stackoverflow.com/questions/1801718/why-can-outer-java-classes-access-inner-class-private-members
帖子中有很多人給予了熱情的回覆,大家可以看一下。要說明這個問題,需要說明一下在什麼樣的情況下使用內部類:
1. 你的某個類中的部分功能需要放在一個單獨的類中實現,這樣比較有利於程式碼的可讀性和可維護性
2. 但是這部分的功能和現在這個類中的一些方法有這密切的關係。
這個時候,你就應該使用內部類,可以看到,內部類的設計目的就是為了將外部類中的一些功能方便地隔離出來,但是為了方便這個類的操作,所以這個類需要對外部類的一些屬性和方法進行訪問。也就是說這個時候,內部類只是外部類的一部分和外部類中的某個成員變數沒有什麼區別,當然可以互相訪問了,包括私有屬性和方法!這是從設計上對這個問題的解釋,從編譯和JVM角度來說的話,那就是java在編譯的時候內部類和外部類的資料處理是共享的,也就是說所有的資料都是可以互相看到的。
下面給出一個測試程式碼,實際測試一個內部類和外部類的互相訪問的問題:

/*************************************************************************
    > File Name: Demo.java
    > Author: Baniel Gao
    > Mail: [email protected] 
    > Created Time: Tue 28 Jun 2016 04:25:01 PM CST
 ************************************************************************/

class OuterClass {

    private
int OuterPrivateInt = 0; public int OuterPublicInt = 1; public OuterClass() { } private void OuterPrivateMethod() { System.out.println("outer private method."); } public void OuterPublicMethod() { System.out.println("outer public method."); } public
void outerTest() { System.out.println("***********************Outer Test***********************"); InnerClass innerObj = new InnerClass(); // access inner private member System.out.println("inner class private int: " + innerObj.InnerPrivateInt); // access inner public member System.out.println("inner class public int: " + innerObj.InnerPublicInt); // call inner public method innerObj.InnerPublicMethod(); // call inner private method innerObj.InnerPrivateMethod(); System.out.println("***********************Outer Test*********************** \n"); // inner test one innerObj.innerTestOne(); // inner test two innerObj.innerTestTwo(); } class InnerClass { private int InnerPrivateInt = 2; public int InnerPublicInt = 3; private void InnerPrivateMethod() { System.out.println("inner private method."); } public void InnerPublicMethod() { System.out.println("inner public method."); } public void innerTestOne() { System.out.println("***********************Inner Test One***********************"); // call outer class private method OuterPrivateMethod(); // call outer class public method OuterPublicMethod(); // access outer class private member System.out.println("outer class private int: " + OuterPrivateInt); // access outer class public member System.out.println("outer class public int: " + OuterPublicInt); System.out.println("***********************Inner Test One*********************** \n"); } public void innerTestTwo() { System.out.println("***********************Inner Test Two***********************"); OuterClass outerObj = new OuterClass(); // access outer class private member System.out.println("outer class private int: " + outerObj.OuterPrivateInt); // access outer class public member System.out.println("outer class public int: " + outerObj.OuterPublicInt); // call outer class private method outerObj.OuterPrivateMethod(); // call outer class public method outerObj.OuterPublicMethod(); System.out.println("***********************Inner Test Two***********************"); } } } public class Demo { public static void main(String[] arg) { OuterClass obj = new OuterClass(); obj.outerTest(); } }

執行結果如下:
這裡寫圖片描述
從實際的執行結果來看,內部類和外部類的訪問就是通行的,可以自由訪問!