內部類:
正常的類是定義在一個.java文本文件的最外層的,也就是,定義一個類,這個類外面沒有任何包含{}作用域的元素了,但是內部類是定義在某個類內部的類。
為什么java要提供這樣的類定義方式呢?因為如果向往常一樣定義一個類,那么要么是public class Cls ,要么是 class Cls,想要用這些類,直接引用即可,但是當編程時如果需要需要定義一個類,卻只想讓某一個類用到這個類,不希望這個類被其他人使用,就用到內部類了。
Java中的內部類分四種:
1. 非靜態內部類
a) 成員內部類 member inner class
b) 局部內部類 local inner class
c) 匿名內部類 anonymous inner class
2. 靜態內部類 static inner class (嵌套類 nested class)
非靜態內部類
非靜態內部類就是沒有static關鍵字修飾的類
需要讓內部類和他的外部類之間有交互時使用
成員內部類:
內部類定義的位置在類中的成員位置,也就是說在類中的最外層的{}里面
成員內部類可以保證讓內部類訪問外部類的所有成員包括私有的,包括靜態的
在外部類之外訪問: 外部類.內部類
在外部類之外new:要用一個已存在的內部類對象來new p.new Inner()
在內部類訪問他的外部類成員:外部類.this.成員
為什么成員內部類可以和外部類之間互相交互呢?
因為成員在定義內部類后,編譯時編譯器自動在內部類中加入一個隱式字段,這個字段是個指向他的外部類對象的引用,在內部類的構造函數中對其進行初始化,
所以,內部類對象持有一個外部類對象的引用,那么二者就能互相訪問。
局部內部類:
定義在某個成員方法中,類似于局部變量的類
用法與局部變量相同,不能用public等修飾
能訪問在該方法的其他位置定義的final變量,非final不可
能訪問該方法所在類的成員
只能在該方法的作用域中使用,也就是外部類不能使用,外部類之外更不能使用
為什么局部內部類只能訪問final局部變量(或者相當于final的)呢?
當局部內部類對該內部類所在的方法的某個局部變量進行訪問時,相當于在內部類里面定義一個成員,然后把局部變量的值賦值給他。
所以 一旦修改這個變量,會讓編譯器認為這個是過期的,那么就不知道該給內部類成員變量哪個值。
所以在內部類中只能使用final外部變量保證這個值不被修改
如果外面的函數中某個值在內部類中用到了,那么這個值不可以繼續被修改
1.內部類使用非final

分析 函數中的變量 i 并沒有被改變,所以這是(相當于final)的變量。可以成功編譯
2.內部類修改非final

編譯錯誤
分析:不能在內部類中修改外部函數中的局部變量。
3.內部類使用非final 在函數中修改

編譯錯誤:
分析:內部類一旦使用了某個外部函數的變量,就相當于編譯器給這個變量自動加了final,所以變量不能被修改了。
4.在函數中修改內部類沒有使用過的非final

編譯成功。
變量j沒有在內部類中使用,所以不會出錯
5.在內部類使用外部函數的final變量
由于final的特性 可以得知,final保證了變量不能被修改,所以無論在哪要改變這個都會出錯,只能在內部類中使用
總結:
對于外部函數中的某個局部變量,只要在內部類中出現了,可以看做編譯器立馬給這個變量加上了final,保證他不會被修改。
對于內部類中沒有出現的局部變量,那么與final無關
靜態內部類:
靜態內部類就是嵌套類
內部類中只能訪問外部類的靜態成員(這點與成員內部類不同),因為static在靜態存儲區
在外部類之外聲明用 外部類.內部類
在類外new 直接 new 外部類.內部類即可,因為不存在對象。
匿名內部類:
不包含名字的內部類
在定義時就產生一個對象并且只使用這一次
常常用于在給一個函數傳入某個參數時使用
定義一個匿名內部類,必須是在一直某個父類或者接口的情況下定義。
定義格式是 new 父類或接口() { 成員 };
匿名內部類因為是匿名的,所以沒有構造方法,想要實現構造方法的功能要用構造代碼塊 {}
匿名內部類只能訪問final局部變量,因為它實際上是一個局部內部類的變種
匿名內部類創建時隱式調用了父類的構造方法,如果父類的構造有參數,那么必須在()括號中傳入(x) 此時不需要final
注:
下劃線代表仍存在疑問。
新聞熱點
疑難解答