Java內部類和外部類互相訪問問題
阿新 • • 發佈:2018-12-26
今天在分析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();
}
}
執行結果如下:
從實際的執行結果來看,內部類和外部類的訪問就是通行的,可以自由訪問!