首先回顧一下匿名內部類的定義和規則,匿名內部類即沒有名字的內部類,內部類即可以將一個類的定義放在另一個類的定義內部,使用內部類可以使代碼顯的更加清晰;
注意:匿名內部類適合創建只需要使用一次的類,創建匿名內部類時會立即創建一個類的實例,并且這個類的定義會立即消失;
另外1.匿名內部類不能是抽象類,因為抽象類無法創建對象;2.匿名內部類必須繼承一個父類或實現一個接口,并且只能有一個;3.匿名內部類不能定義構造器,這很容易理解,因為構造器的名字必須和類名一樣。
如下程序所示,通過繼承父類來創建匿名內部類,實現接口和其類似;
abstract class Animal {public abstract void voice();}public class Test {public static void main(String[] args) {Animal a = new Animal() {public void voice() {System.out.PRintln("汪汪汪!");}};a.voice();}}
下面為不使用匿名內部類的程序
abstract class Animal { public abstract void voice();} class Dog extends Animal { public void voice() { System.out.println("汪汪汪!"); }}public class Test {public static void main(String[] args) {Animal a=new Dog();a.voice();}}
對比以上兩種方式可知采用匿名內部類使程序變得更加的簡潔;
接下來介紹一下java8關于匿名內部類的改進部分:
Java8將“被局部內部類和匿名內部類訪問的局部變量必須使用final修飾”這個限制去掉了,若局部變量被匿名內部類訪問,則相當于自動的使用了final,其實就是變簡單了,但還是要注意可能會出現錯誤,比如下面的例子
interface Animal {public void voice();}public class Test {public static void main(String[] args) {int voiceNumber=2;//聲音大小Animal a = new Animal() {public void voice() {System.out.println(voiceNumber);}};a.voice();}}
在Java8之前System.out.println(voiceNumber);這行代碼會被提示錯誤,提示內容為"Cannot refer to a non-final variable voiceNumber inside an inner class defined in a different method",如果要使用voiceNumber,必須使用final進行修飾;但是對于Java8而言,如果在int voiceNumber=2;后加上代碼voiceNumber=3;
則會造成編譯錯誤,提示為“從內部類引用的本地變量必須是最終變量或實際上的最終變量 ”,這是因為voiceNumber這個局部變量已經被匿名內部類訪問過了,相當于被final修飾了;
注意:在使用MyEclipse等其他工具進行編寫時可能不加final會提示錯誤,本人使用MyEclipse時出現了錯誤,但使用命令行測試時沒有錯誤!
至于為什么使用final,可參考http://android.blog.51cto.com/268543/384844
最后,Java8這個功能的意思是對于被匿名內部類訪問的局部變量,可以用final修飾,也可以不用,但必須按照有final修飾的方式來使用,即一次賦值后,以后不能重新賦值。
以上部分內容參考了《瘋狂Java講義》,并加入了一些自己的理解,希望對大家有所幫助。
新聞熱點
疑難解答