匿名內(nèi)部類

  • 匿名內(nèi)部類是什么?

引子
public abstract class Animal {
    abstract void sayHello();
}

假如現(xiàn)在有一個(gè)Animal的抽象類,他有一個(gè)sayHello的抽象方法.在我們的程序中,有時(shí)候我們需要一只貓,并且讓它們sayHello,這時(shí)我們會(huì)新建一個(gè)Cat類,繼承Animal,然后實(shí)現(xiàn)sayHello,比如

public class Cat extends Animal {
    @Override
    void sayHello() {
        System.out.println("hello, I am a cat");
    }
}

但是這時(shí)候如果我們又需要一只狗,怎么辦?當(dāng)然是新建一個(gè)Dog類,繼承Animal,然后實(shí)現(xiàn)sayHello,比如

public class Dog extends Animal{

    @Override 
    void sayHello() {
        System.out.println("hello, I am a dog");
    }
}

接著,我們又需要雞鴨鵝,我們又得新建雞鴨鵝類,繼承Animal,然后實(shí)現(xiàn)sayHello,但是我們新建的這些子類,很多都是只用到一次,然后就不會(huì)再用到了,這時(shí)我們會(huì)感覺(jué)新建類這種操作是比較麻煩的,而且時(shí)間久了,那些類會(huì)越來(lái)越多,那有沒(méi)有更簡(jiǎn)便的方法呢?有的,那就是匿名內(nèi)部類.我們來(lái)看看用匿名內(nèi)部類來(lái)實(shí)現(xiàn)一只貓是怎么樣的?

public class AnimalTest {
    public static void main(String[] args) {
        Animal cat = new Animal() {
            @Override 
            void sayHello() {
                System.out.println("hello, I am a cat");
            }
        };
    }
}

對(duì)比新建類的方式,用匿名內(nèi)部類的方式顯然更加簡(jiǎn)單優(yōu)雅一點(diǎn),我們?nèi)粢獔?zhí)行sayHello的方法,只需要cat.sayHello()即可.

匿名內(nèi)部類的實(shí)現(xiàn)方式

除了上面實(shí)現(xiàn)一個(gè)抽象類和抽象方法,匿名內(nèi)部類還可以是實(shí)現(xiàn)一個(gè)接口類和接口方法,比如

        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println("I am " + Thread.currentThread().getName());
            }
        };
        Thread t = new Thread(r);
        t.start();

你打開(kāi)Runnable一看,就知道原來(lái)Runnable是一個(gè)接口類

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}
匿名

之所以叫做匿名,我感覺(jué)應(yīng)該是它不像我們的貓狗雞鴨鵝一樣,有自己的類名,匿名內(nèi)部類用的是抽象類的類名和接口名

內(nèi)部類

之所以說(shuō)是內(nèi)部類,是因?yàn)樗挥眯陆ㄒ粋€(gè)類,而是寫(xiě)在方法里面.

  • 匿名內(nèi)部類的原理

public class AnimalTest {
    public static void main(String[] args) {
        final Integer age = 3;
        Animal cat = new Animal() {
            @Override
            void sayHello() {
                System.out.println("I am a cat, age = " + age);
            }
        };
        cat.sayHello();
    }
}

我們把該段代碼編譯以后,實(shí)際上是生成兩個(gè)文件


編碼后的文件

查看AnimalTest$1.class

package anonymous;
final class AnimalTest$1 extends Animal {
    AnimalTest$1(Integer var1) {
        this.val$age = var1;
    }
    void sayHello() {
        System.out.println("I am a cat, age = " + this.val$age);
    }
}

再查看AnimalTest.class

package anonymous;
import anonymous.AnimalTest.1;
public class AnimalTest {
    public AnimalTest() {
    }
    public static void main(String[] args) {
        Integer age = Integer.valueOf(3);
        Animal cat = new 1(age);
        cat.sayHello();
    }
}

變異后實(shí)際上偷偷生成一個(gè)animal的子類,在AnimalTest的主方法中,只是創(chuàng)建一個(gè)這個(gè)子類的對(duì)象.

為什么要用final

我們發(fā)現(xiàn)在匿名內(nèi)部類中使用內(nèi)名內(nèi)部類外面的局部變量,必須要把局部變量修飾成final,這是為什么呢?
我們看上面的代碼,會(huì)發(fā)現(xiàn)局部變量是通過(guò)構(gòu)造函數(shù)傳進(jìn)匿名內(nèi)部類中的,而且匿名內(nèi)部類中使用的并不是這個(gè)局部變量本身,而是它的一個(gè)副本.這樣子就會(huì)產(chǎn)生一個(gè)問(wèn)題,如果我們?cè)谀涿麅?nèi)部類中修改局部變量的值,實(shí)際上并不是修改匿名內(nèi)部類外面的局部變量的值,這時(shí)候就會(huì)產(chǎn)生數(shù)據(jù)不同步的情況.為了避免這種情況的發(fā)生,干脆把局部變量修飾成final,不可修改.

  • 什么時(shí)候可以用到匿名內(nèi)部類?

同樣的某些接口或者抽象方法的具體實(shí)現(xiàn)在程序中只會(huì)用到一次,就可以用匿名內(nèi)部類.比如我們?cè)诔绦蛑心硞€(gè)地方需要新建一個(gè)線程去處理把某個(gè)特定的緩存清除掉,注意整個(gè)程序只有一個(gè)地方會(huì)用到這個(gè)清除某個(gè)特定緩存的操作,或者其它地方需要清除的是其他不同的緩存

        Thread t = new Thread(){
            @Override
            public void run(){
                CacheUtil.remove(CACHE_ONE);
            }
        };
        t.start();

假如同樣的某些接口或者抽象方法的具體實(shí)現(xiàn)在程序中只會(huì)用到多次,就是說(shuō)上面的操作還有其他很多地方都會(huì)用到,這時(shí)候我們就可以新建一個(gè)Thread內(nèi),實(shí)現(xiàn)run方法.比如

public class CacheThread extends Thread {
    @Override
    public void run() {
        CacheUtil.remove(CACHE_ONE);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市脖旱,隨后出現(xiàn)的幾起案子罢吃,更是在濱河造成了極大的恐慌咬像,老刑警劉巖议街,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贩耐,死亡現(xiàn)場(chǎng)離奇詭異洽损,居然都是意外死亡蛉幸,警方通過(guò)查閱死者的電腦和手機(jī)肖粮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)孤页,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人涩馆,你說(shuō)我怎么就攤上這事行施。” “怎么了魂那?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵蛾号,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我涯雅,道長(zhǎng)鲜结,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任斩芭,我火速辦了婚禮轻腺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘划乖。我一直安慰自己贬养,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布琴庵。 她就那樣靜靜地躺著误算,像睡著了一般。 火紅的嫁衣襯著肌膚如雪迷殿。 梳的紋絲不亂的頭發(fā)上儿礼,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音庆寺,去河邊找鬼蚊夫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛懦尝,可吹牛的內(nèi)容都是我干的知纷。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼陵霉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼琅轧!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起踊挠,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤乍桂,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體睹酌,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡权谁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了忍疾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闯传。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖卤妒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情字币,我是刑警寧澤则披,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站洗出,受9級(jí)特大地震影響士复,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜翩活,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一阱洪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧菠镇,春花似錦冗荸、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至隘梨,卻和暖如春程癌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背轴猎。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工嵌莉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人捻脖。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓锐峭,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親郎仆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子只祠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容