Java內部類知識匯總
Java內部類
一、 含義
在Java編程語言里,程序是由類(class)構建而成的。在一個類的內部也可以聲明類,我們把這樣的類叫做內部類。
二、 作用
•實現(xiàn)了更好的封裝,我們知道,普通類(非內部類)的訪問修飾符不能為private或protected,而內部類可以。當我們將內部類聲明為private時,只有外部類可以訪問內部類,很好地隱藏了內部類。
•內部類可以繼承(extends)或實現(xiàn)(implements)其他的類或接口,而不受外部類的影響。
•內部類可以直接訪問外部類的字段和方法,即使是用private修飾的,相反的,外部類不能直接訪問內部類的成員。
三、 原理
內部類是一個編譯時的概念,編譯后會生成兩個獨立的class文件,如下:
public class Outer{
private String outerName = "outer";
class Inner{
private String innerName = "inner";
}
}
編譯后的文件如下圖:

編譯后Outer.Inner被重命名為Outer$Inner,句點(.)被替換成了美元符號($)。
四、 分類
Java內部類可分為成員內部類、局部內部類、匿名內部類、靜態(tài)內部類。
1) 成員內部類
成員內部類可以看成是外部類的一個成員,在成員內部類中無法聲明靜態(tài)成員,但static final字段是個例外。我們知道加載類時,會先初始化靜態(tài)成員,如果成員內部類有靜態(tài)成員,那么內部類就會在外部類之前生成,而內部類是為外部類服務的,內部類在外部類之前就生成可能會脫離掌控。在實例化成員內部類時,成員內部類會持有一個外部類當前對象的引用,這樣在成員內部類中就可以直接訪問外部類的成員,即使是private修飾的。
import static java.lang.System.out;
public class Outer{
private String outerName = "outer";
//外部類無法直接訪問內部類的成員,需要實例化內部類對象
private Inner inner = new Inner();
public class Inner{
private String innerName = "inner";
public void show(){
out.println(outerName); //可以直接訪問外部類的成員
}
}
public void show(){
out.println(inner.innerName);
inner.show();
}
public static void main(String[] args){
Outer outer = new Outer();
outer.show();
//實例化內部類
Outer.Inner inner = outer.new Inner();
inner.show();
}
}
運行結果:
inner
outer
outer
成員內部類對外部類對象的引用,是通過在this前面加上外部類的名字構成的,這種形式叫作
限定-this,out.println(outerName)與out.println(Outer.this.outerName)是等價的。
2) 局部內部類
局部內部類的使用和成員內部類的使用基本一致,只是局部內部類定義在外部類的方法中,就像局部變量一樣,并不是外部類的成員。局部內部類在方法外是無法訪問到的,但它的實例可以從方法中返回,并且實例在不再被引用之前會一直存在。局部內部類也可以訪問所在方法的局部變量、方法參數(shù)等,限制是局部變量或方法參數(shù)只有在聲明為final時才能被訪問?! ?/p>
import static java.lang.System.out;
public class Outer{
private String outerName = "outer";
public void show(final String str){ //方法參數(shù)為final類型
class Inner{
public void print(){
out.println(outerName+str);
}
}
Inner inner = new Inner();
inner.print();
}
public static void main(String[] args){
Outer outer = new Outer();
outer.show(":lalala");
}
}
運行結果:
outer:lalala
3) 匿名內部類
可以把匿名內部類想象成是沒有類名的局部內部類,匿名內部類有以下特點:
1、匿名內部類不能有構造器,匿名內部類沒有類名,肯定無法聲明構造器。
2、匿名內部類必須繼承或實現(xiàn)一個接口,指定給new的類型為匿名類的超類型,匿名類不能有顯示的extends或implements子句,也不能有任何修飾符。
3、匿名內部類和成員內部類、局部內部類一樣,也不能聲明靜態(tài)成員。
import static java.lang.System.out;
public class Outer{
private String outerName = "outer";
public void show(final String str){
new Inner(){ //實現(xiàn)了Inner接口
public void print(){
out.println(outerName+str);
}
}.print();
}
public static void main(String[] args){
Outer outer = new Outer();
outer.show(":lalala");
}
}
interface Inner{
void print();
}
運行結果:
outer:lalala
4) 靜態(tài)內部類
靜態(tài)內部類,有的書上也稱為嵌套類,聲明它時需要用static修飾符,靜態(tài)內部類不同于前三種內部類,靜態(tài)內部類不會持有外部類當前對象的引用,所以在靜態(tài)內部類中無法訪問外部類的非靜態(tài)成員,可以這么說,靜態(tài)內部類不依賴于外部類?!?/p>
import static java.lang.System.out;
public class Outer{
private String outerName = "outer";
private static int id = 123;
private Inner inner = new Inner();
public static class Inner{
public void print1(){
//out.println(outerName); 無法訪問外部類的非靜態(tài)成員
out.println(id);
}
public static void print2(){
out.println(id);
}
}
public void show(){
inner.print1();
}
public static void main(String[] args){
Outer outer = new Outer();
outer.show();
Outer.Inner.print2(); //直接通過類名訪問靜態(tài)內部類
}
}
相關文章
SpringAnimation 實現(xiàn)菜單從頂部彈出從底部消失動畫效果
最近做項目遇到這樣一個需求,要求實現(xiàn)一種菜單,菜單從頂部彈入,然后從底部消失,頂部彈入時,有一個上下抖動的過程,底部消失時,先向上滑動,然后再向下滑動消失。下面給大家?guī)砹藢崿F(xiàn)代碼,感興趣的朋友一起看看吧2018-05-05
如何優(yōu)雅的實現(xiàn)將Collection轉為Map
這篇文章主要介紹了如何優(yōu)雅的實現(xiàn)將Collection轉為Map,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03
Mybatis-plus使用注解 @TableField(exist = false)
這篇文章主要介紹了Mybatis-plus使用注解 @TableField(exist = false),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03
JAVA集成Freemarker生成靜態(tài)html過程解析
這篇文章主要介紹了JAVA集成Freemarker生成靜態(tài)html過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06

