很多學習Java的人都知道Java有內部類,但是我想大部分人在開發中都很少使用內部類編寫代碼。大部人也不知道內部類有什麼作用。
接下來,我們就一起來聊聊內部類。
Java中有:成員內部類,靜態內部類,局部內部類,匿名內部類 四種。
成員內部類:
public class OutClass{
private class InnerClass{
}
}
1、直接在外部類中編寫內部類,該內部類看起來好想是和外部類的字段方法平級的,其實並不然,因爲在編譯代碼的時候,
會將內部類單獨編譯成一個文件,其中文件名以$標識。
2、成員內部類允許使用private,protected,默認,public所有的權限修飾符修飾。
3、成員內部類的創建必須要依賴於外部類的實例。
4、成員內部類可以隨意的訪問成員外部類的成員變量。
靜態內部類:
public class OutClass{
public static InnerClass{
}
}
1、靜態內部類以static關鍵字修飾
2、靜態內部類允許使用private,protected,默認,public所有的權限修飾符修飾。
3、靜態內部類的創建不需要依賴外部類的實例,可以直接通過外部類進行創建。
4、靜態內部類只能訪問外部類的靜態字段和靜態方法。
局部內部類:
public class OutClass{
public void method(){
class InnerClass{
}
}
}
1、局部內部類是在外部類方法的外部的方法內
2、局部內部類不允許任何修飾符進行修飾(因爲局部內部類所在的方法上已經有權限了,所有沒有必要再局部內部類再設置權限)
3、局部內部類只能在該方法中實例化,不能通過外部實例化。
4、局部內部類和該方法的生命週期不一致。
5、局部內部類如果要訪問該方法的局部變量,那麼局部變量必須設置爲final類型 。訪問外部類的變量不必設置爲final。
匿名內部類:
public interface Iinner{
void say();
}
public class OutClass{
public void sayMethod(){
new Iinner() {
@Override
public void say() {
System.out.println("hello");
}
}.say();
}
}
1、匿名內部類只能被調用一次
2、匿名內部類可以訪問外部類的成員變量,並且變量不必用final修飾
3、匿名內部類可以訪問方法的局部變量
上面我們說了,局部內部類訪問方法局部變量,局部變量必須要加final,這是爲什麼呢?
首先說一下,因爲局部內部類是一個類,實例化後是存放到堆中去了,而方法在它執行完畢後就銷燬了,所有,局部內部類一般要比方法的生命週期長,
那麼問題來了,方法都銷燬了,局部變量自然也沒有了,如果局部內部類中還需要訪問該局部變量,那不完蛋了,找不到啊。所以局部內部類訪問的局部變量
並不是方法中的那個變量,編譯源代碼的時候,會將該局部變量拷貝一份放到局部內部類中,因爲局部內部類其實也是一個單獨的文件。
不過這樣又有問題了,你想啊,我們在這裏創建了局部內部類,並且操作了局部變量,我們是想操作方法中的局部變量啊!!!你給我了個副本,這幾個意思???
這不是搞我們麼,隨便我們在內部類怎麼折騰,方法中的局部變量都沒啥影響啊,而且方法中的變量更改了,也不關局部內部類啥事啊。爲了避免出現這樣的數據
不統一,所有我們要禁止局部變量進行修改,要保證變量的統一。這其實也是無奈之舉啊。
不過對於引用型數據,我們仍然是可以修改裏面的數據的,因爲我們方法中的引用和局部內部類中的引用是一致的,都指向的統一地址。
使用內部類對於我們來說有什麼好處呢??
1、我們知道Java只能單繼承,使用內部類相當於變相的使我們擁有了多繼承的能力。
爲什麼這麼說呢?因爲內部類可以直接操作外部類的變量啊,既然能夠操作外部類,那麼我們用內部類繼承某個類之後,在操作外部類變量,不就相當於外部類
直接繼承該類了嗎?
2、使用內部類可以將類私有化,隱藏內部實現細節,方便以後進行修改內部實現。
3、使用內部類有時可以使我們的實現更加簡潔,層次分明,代碼優雅。(例如:如果一個類不需要外部調用,也僅僅只會被另一個類調用,那麼我們完全可以將該類
定義成調用類的內部類啊,這樣,還隱藏了內部實現細節,還不用單獨創建一個類文件。)
本文肯定還有很多沒有提到的地方,本人水平有限,大家有什麼意見可以留言,我會及時修改。