一篇文章讓你徹底了解Java內(nèi)部類

簡(jiǎn)書的格式,有點(diǎn)吃不消啊

內(nèi)容整理自《Thinking in Java》(第四版) 第10章 PDF下載地址


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

將一個(gè)類的定義,放在另一個(gè)類的定義內(nèi)部,那這個(gè)類坝辫,就是內(nèi)部類


為什么需要內(nèi)部類?

一般來說射亏,內(nèi)部類繼承自某個(gè)類或?qū)崿F(xiàn)某個(gè)接口阀溶,內(nèi)部類的代碼操作創(chuàng)建其的外圍類的對(duì)象。所以你可以認(rèn)為內(nèi)部類提供了某種進(jìn)入其外圍類的窗口鸦泳。


內(nèi)部類的優(yōu)雅之處:

每個(gè)內(nèi)部類都能獨(dú)立的繼承一個(gè)(接口的)實(shí)現(xiàn)银锻,無論外部類是否已經(jīng)繼承了一個(gè)(接口的)實(shí)現(xiàn),對(duì)內(nèi)部類都沒有影響做鹰。

內(nèi)部類主要有以下幾類:

  • A:成員內(nèi)部類
  • B:局部內(nèi)部類
  • C:靜態(tài)內(nèi)部類
  • D:匿名內(nèi)部類

注意:

  1. 定義了成員內(nèi)部類后击纬,必須使用外部類對(duì)象來創(chuàng)建內(nèi)部類對(duì)象,而不能直接去 new 一個(gè)內(nèi)部類對(duì)象钾麸,
    即:內(nèi)部類 對(duì)象名 = 外部類對(duì)象.new 內(nèi)部類( );
  2. 外部類是不能直接使用內(nèi)部類的成員和方法滴更振,可先創(chuàng)建內(nèi)部類的對(duì)象,然后通過內(nèi)部類的對(duì)象來訪問其成員變量和方法饭尝。
  3. 可先創(chuàng)建內(nèi)部類的對(duì)象肯腕,然后通過內(nèi)部類的對(duì)象來訪問其成員變量和方法。HelloWorld.this.name

A:成員內(nèi)部類

作為外部類的一個(gè)成員存在钥平,與外部類的屬性实撒、方法并列。

public class Outer {
    
    private static int i = 1;
    private int j = 10;
    private int k = 20;


    public static void outerF1() {
    }

    /**
     * 外部類的靜態(tài)方法訪問成員內(nèi)部類涉瘾,與在外部類外部訪問成員內(nèi)部類一樣
     */
    public static void outerF4() {
        //step1 建立外部類對(duì)象
        Outer out = new Outer();
        //step2 根據(jù)外部類對(duì)象建立內(nèi)部類對(duì)象
        Inner inner = out.new Inner();
        //step3 訪問內(nèi)部類的方法
        inner.innerF1();
    }

    public static void main(String[] args) {

        /*
         * outerF4();該語句的輸出結(jié)果和a下面三條語句的輸出結(jié)果一樣
         *如果要直接創(chuàng)建內(nèi)部類的對(duì)象知态,不能想當(dāng)然地認(rèn)為只需加上外圍類Outer的名字,
         *就可以按照通常的樣子生成內(nèi)部類的對(duì)象立叛,而是必須使用此外圍類的一個(gè)對(duì)象來
         *創(chuàng)建其內(nèi)部類的一個(gè)對(duì)象:
         *Outer.Inner outin = out.new Inner()
         *因此负敏,除非你已經(jīng)有了外圍類的一個(gè)對(duì)象,否則不可能生成內(nèi)部類的對(duì)象秘蛇。因?yàn)榇?         *內(nèi)部類的對(duì)象會(huì)悄悄地鏈接到創(chuàng)建它的外圍類的對(duì)象其做。如果你用的是靜態(tài)的內(nèi)部類顶考,
         *那就不需要對(duì)其外圍類對(duì)象的引用。
         */
        Outer out = new Outer();
        Outer.Inner outin = out.new Inner();
        outin.innerF1();
    }

    public void outerF2() {
    }

    /**
     * 外部類的非靜態(tài)方法訪問成員內(nèi)部類
     */
    public void outerF3() {
        Inner inner = new Inner();
        inner.innerF1();
    }

    /**
     * 成員內(nèi)部類中妖泄,不能定義靜態(tài)成員
     * 成員內(nèi)部類中村怪,可以訪問外部類的所有成員
     */
    class Inner {
        // static int innerI = 100;內(nèi)部類中不允許定義靜態(tài)變量
        // 內(nèi)部類和外部類的實(shí)例變量可以共存
        int j = 100;
        int innerI = 1;


        void innerF1() {
            System.out.println(i);
            //在內(nèi)部類中訪問內(nèi)部類自己的變量直接用變量名
            System.out.println(j);
            //在內(nèi)部類中訪問內(nèi)部類自己的變量也可以用this.變量名
            System.out.println(this.j);
            //在內(nèi)部類中訪問外部類中與內(nèi)部類同名的實(shí)例變量用外部類名.this.變量名
            System.out.println(Outer.this.j);
            //如果內(nèi)部類中沒有與外部類同名的變量,則可以直接用變量名訪問外部類變量
            System.out.println(k);
            outerF1();
            outerF2();
        }
    }
}

<font color=red>注意:內(nèi)部類是一個(gè)編譯時(shí)的概念浮庐,一旦編譯成功,就會(huì)成為完全不同的兩類柬焕。</font>

對(duì)于一個(gè)名為outer的外部類和其內(nèi)部定義的名為inner的內(nèi)部類审残。編譯完成后出現(xiàn)outer.class和outer$inner.class兩類。


B:局部內(nèi)部類

在方法中定義的內(nèi)部類稱為局部內(nèi)部類斑举。與局部變量類似搅轿,局部內(nèi)部類不能有訪問說明符,因?yàn)樗皇峭鈬惖囊徊糠指荤瑁撬梢栽L問當(dāng)前代碼塊內(nèi)的常量璧坟,和此外圍類所有的成員。


public class Outer {

    private int s = 100;
    private int outI = 1;

    public static void main(String[] args) {
        // 訪問局部內(nèi)部類必須先有外部類對(duì)象
        Outer out = new Outer();
        out.f(3);
    }

    public void f(final int k) {
        final int s = 200;
        int i = 1;
        final int j = 10;


        /**
         * 定義在方法內(nèi)部
         */
        class Inner {
            // 可以定義與外部類同名的變量
            int s = 300;
            int innerI = 100;

            // static int m = 20; 不可以定義靜態(tài)變量
            Inner(int k) {
                innerF(k);
            }
            void innerF(int k) {
                // java如果內(nèi)部類沒有與外部類同名的變量赎懦,在內(nèi)部類中可以直接訪問外部類的實(shí)例變量
                System.out.println(outI);
                // 可以訪問外部類的局部變量(即方法內(nèi)的變量)雀鹃,但是變量必須是final的
                System.out.println(j);
                //System.out.println(i);
                // 如果內(nèi)部類中有與外部類同名的變量,直接用變量名訪問的是內(nèi)部類的變量
                System.out.println(s);
                // 用this.變量名訪問的也是內(nèi)部類變量
                System.out.println(this.s);
                // 用外部類名.this.內(nèi)部類變量名訪問的是外部類變量
                System.out.println(Outer.this.s);
            }
        }
        new Inner(k);
    }
}

C:靜態(tài)內(nèi)部類(嵌套類):

注意:前兩種內(nèi)部類與變量類似励两,所以可以對(duì)照參考變量

如果你不需要內(nèi)部類對(duì)象與其外圍類對(duì)象之間有聯(lián)系黎茎,那你可以將內(nèi)部類聲明為static。這通常稱為嵌套類(nested class)当悔。想要理解static應(yīng)用于內(nèi)部類時(shí)的含義傅瞻,你就必須記住,普通的內(nèi)部類對(duì)象隱含地保存了一個(gè)引用盲憎,指向創(chuàng)建它的外圍類對(duì)象嗅骄。然而,當(dāng)內(nèi)部類是static的時(shí)饼疙,就不是這樣了溺森。嵌套類意味著:

  1. 要?jiǎng)?chuàng)建嵌套類的對(duì)象,并不需要其外圍類的對(duì)象窑眯。
  2. 不能從嵌套類的對(duì)象中訪問非靜態(tài)的外圍類對(duì)象儿惫。

<font color=red>單例模式:由于靜態(tài)內(nèi)部類的加載機(jī)制,決定了他可以使用來處理單例模式,而且性能客觀</font>單例模式相關(guān)內(nèi)容>>點(diǎn)我


public class Outer {
    private static int i = 1;
    private int j = 10;

    public static void outerF1() {
    }

    public static void main(String[] args) {
        new Outer().outerF3();
    }

    public void outerF2() {
    }

    public void outerF3() {
        // 外部類訪問內(nèi)部類的靜態(tài)成員:內(nèi)部類.靜態(tài)成員
        System.out.println(Inner.inner_i);
        Inner.innerF1();
        // 外部類訪問內(nèi)部類的非靜態(tài)成員:實(shí)例化內(nèi)部類即可
        Inner inner = new Inner();
        inner.innerF2();
    }

    /**
     * 靜態(tài)內(nèi)部類可以用public,protected,private修飾
     * 靜態(tài)內(nèi)部類中可以定義靜態(tài)或者非靜態(tài)的成員
     */
    static class Inner {
        static int inner_i = 100;
        int innerJ = 200;

        static void innerF1() {
            // 靜態(tài)內(nèi)部類只能訪問外部類的靜態(tài)成員(包括靜態(tài)變量和靜態(tài)方法)
            System.out.println("Outer.i" + i);
            outerF1();
        }


        void innerF2() {
            // 靜態(tài)內(nèi)部類不能訪問外部類的非靜態(tài)成員(包括非靜態(tài)變量和非靜態(tài)方法)
            // System.out.println("Outer.i"+j);
            // outerF2();
        }
    }
}

靜態(tài)內(nèi)部類和成員內(nèi)部類的區(qū)別

生成一個(gè)靜態(tài)內(nèi)部類不需要外部類成員
靜態(tài)內(nèi)部類的對(duì)象可以直接生成:
Outer.Inner in = new Outer.Inner();
而不需要通過生成外部類對(duì)象來生成。這樣實(shí)際上使靜態(tài)內(nèi)部類成為了一個(gè)頂級(jí)類
(正常情況下伸但,你不能在接口內(nèi)部放置任何代碼肾请,但嵌套類可以作為接口的一部分,因?yàn)樗莝tatic 的更胖。只是將嵌套類置于接口的命名空間內(nèi)铛铁,這并不違反接口的規(guī)則)


D:匿名內(nèi)部類(from thinking in java 3th)

匿名內(nèi)部類就是沒有名字的內(nèi)部類隔显。

什么情況下需要使用匿名內(nèi)部類?

如果滿足下面的一些條件饵逐,使用匿名內(nèi)部類是比較合適的:

  • 只用到類的一個(gè)實(shí)例括眠。
  • 類在定義后馬上用到。
  • 類非常斜度ā(SUN推薦是在4行代碼以下)
  • 給類命名并不會(huì)導(dǎo)致你的代碼更容易被理解掷豺。

在使用匿名內(nèi)部類時(shí),要記住以下幾個(gè)原則:

  1. 匿名內(nèi)部類一般不能有構(gòu)造方法薄声。
  2. 匿名內(nèi)部類不能定義任何靜態(tài)成員当船、方法和類。
  3. 匿名內(nèi)部類不能是public,protected,private,static默辨。
  4. 只能創(chuàng)建匿名內(nèi)部類的一個(gè)實(shí)例德频。
  5. 一個(gè)匿名內(nèi)部類一定是在new的后面,用其隱含實(shí)現(xiàn)一個(gè)接口或?qū)崿F(xiàn)一個(gè)類缩幸。
  6. 因匿名內(nèi)部類為局部內(nèi)部類壹置,所以局部內(nèi)部類的所有限制都對(duì)其生效。

下面的例子看起來有點(diǎn)奇怪:

// 在方法中返回一個(gè)匿名內(nèi)部類
public class Parcel6 {
    public static void main(String[] args) {
        Parcel6 p = new Parcel6();
        Contents c = p.cont();
    }

    public Contents cont() {
        return new Contents() {
            private int i = 11;


            public int value() {
                return i;
            }
        }; // 在這里需要一個(gè)分號(hào)
    }
}

cont()方法將下面兩個(gè)動(dòng)作合并在一起:返回值的生成表谊,與表示這個(gè)返回值的類的定義钞护!
  進(jìn)一步說,這個(gè)類是匿名的爆办,它沒有名字患亿。更糟的是,看起來是你正要?jiǎng)?chuàng)建一個(gè)Contents對(duì)象:

return new Contents()

但是押逼,在到達(dá)語句結(jié)束的分號(hào)之前步藕,你卻說:“等一等,我想在這里插入一個(gè)類的定義”:

return new Contents() {
    private int i = 11;

    public int value() {
        return i;
    }
};

這種奇怪的語法指的是:“創(chuàng)建一個(gè)繼承自Contents的匿名類的對(duì)象挑格×撸”通過new 表達(dá)式返回的引用被自動(dòng)向上轉(zhuǎn)型為對(duì)Contents的引用。匿名內(nèi)部類的語法是下面例子的簡(jiǎn)略形式:

class MyContents implements Contents {
    private int i = 11;

    public int value() {
        return i;
    }
}
return new MyContents();

在這個(gè)匿名內(nèi)部類中漂彤,使用了缺省的構(gòu)造器來生成Contents雾消。下面的代碼展示的是,如果你的基類需要一個(gè)有參數(shù)的構(gòu)造器挫望,應(yīng)該怎么辦:

public class Parcel7 {
    public static void main(String[] args) {
        Parcel7 p = new Parcel7();
        Wrapping w = p.wrap(10);
    }

    public Wrapping wrap(int x) {
        // Base constructor call:
        // Pass constructor argument.
        return new Wrapping(x) { 
            public int value() {
                return super.value() * 47;
            }
        }; // Semicolon required
    }
}

只需簡(jiǎn)單地傳遞合適的參數(shù)給基類的構(gòu)造器即可立润,這里是將x 傳進(jìn)new Wrapping(x)。在匿名內(nèi)部類末尾的分號(hào)媳板,并不是用來標(biāo)記此內(nèi)部類結(jié)束(C++中是那樣)桑腮。實(shí)際上,它標(biāo)記的是表達(dá)式的結(jié)束蛉幸,只不過這個(gè)表達(dá)式正巧包含了內(nèi)部類罷了破讨。因此丛晦,這與別的地方使用的分號(hào)是一致的。

如果在匿名類中定義成員變量提陶,你同樣能夠?qū)ζ鋱?zhí)行初始化操作:

public class Parcel8 {
    public static void main(String[] args) {
        Parcel8 p = new Parcel8();
        Destination d = p.dest("Tanzania");
    }

    // Argument must be final to use inside
    // anonymous inner class:
    public Destination dest(final String dest) {
        return new Destination() {
            private String label = dest;

            public String readLabel() {
                return label;
            }
        };
    }
}

如果你有一個(gè)匿名內(nèi)部類烫沙,它要使用一個(gè)在它的外部定義的對(duì)象,編譯器會(huì)要求其參數(shù)引用是final 型的隙笆,就像dest()中的參數(shù)锌蓄。如果你忘記了,會(huì)得到一個(gè)編譯期錯(cuò)誤信息撑柔。如果只是簡(jiǎn)單地給一個(gè)成員變量賦值瘸爽,那么此例中的方法就可以了。但是乏冀,如果你想做一些類似構(gòu)造器的行為,該怎么辦呢洋只?在匿名類中不可能有已命名的構(gòu)造器(因?yàn)樗緵]名字A韭佟),但通過實(shí)例初始化识虚,你就能夠達(dá)到為匿名內(nèi)部類“制作”一個(gè)構(gòu)造器的效果肢扯。像這樣做:

abstract class Base {
    public Base(int i) {
        System.out.println("Base constructor, i = " + i);
    }

    public abstract void f();
}


public class AnonymousConstructor {
    public static Base getBase(int i) {
        return new Base(i) {
            {
                System.out.println("Inside instance initializer");
            }

            public void f() {
                System.out.println("In anonymous f()");
            }
        };
    }

    public static void main(String[] args) {
        Base base = getBase(47);
        base.f();
    }
}

在此例中,不要求變量i 一定是final 的担锤。因?yàn)閕 被傳遞給匿名類的基類的構(gòu)造器蔚晨,它并不會(huì)在匿名類內(nèi)部被直接使用。下例是帶實(shí)例初始化的“parcel”形式肛循。注意dest()的參數(shù)必須是final铭腕,因?yàn)樗鼈兪窃谀涿悆?nèi)被使用的。


public class Parcel9 {
    public Destinationdest(final String dest, final float price) {
        return new Destination() {
            private int cost;
            private String label = dest;

            // Instance initialization for each object:
            {
                cost = Math.round(price);
                if (cost > 100)
                    System.out.println("Over budget!");
            }

            public String readLabel() {
                return label;
            }
        };
    }

    public static void main(String[] args) {
        Parcel9 p = new Parcel9();
        Destination d = p.dest("Tanzania", 101.395F);
    }
}

在實(shí)例初始化的部分多糠,你可以看到有一段代碼累舷,那原本是不能作為成員變量初始化的一部分而執(zhí)行的(就是if 語句)。所以對(duì)于匿名類而言夹孔,實(shí)例初始化的實(shí)際效果就是構(gòu)造器被盈。當(dāng)然它受到了限制:你不能重載實(shí)例初始化,所以你只能有一個(gè)構(gòu)造器搭伤。


從多層嵌套類中訪問外部

一個(gè)內(nèi)部類被嵌套多少層并不重要只怎,它能透明地訪問所有它所嵌入的外圍類的所有成員,如下所示:


class MNA {
    private void f() {
    }

    class A {
        private void g() {
        }

        public class B {
            void h() {
                g();
                f();
            }
        }
    }
}

public class MultiNestingAccess {
    public static void main(String[] args) {
        MNA mna = new MNA();
        MNA.A mnaa = mna.new A();
        MNA.A.B mnaab = mnaa.new B();
        mnaab.h();
    }
}

可以看到在MNA.A.B中怜俐,調(diào)用方法g()和f()不需要任何條件(即使它們被定義為private)身堡。這個(gè)例子同時(shí)展示了如何從不同的類里面創(chuàng)建多層嵌套的內(nèi)部類對(duì)象的基本語法∨睦穑“.new”語法能產(chǎn)生正確的作用域盾沫,所以你不必在調(diào)用構(gòu)造器時(shí)限定類名裁赠。


內(nèi)部類的重載問題

如果你創(chuàng)建了一個(gè)內(nèi)部類,然后繼承其外圍類并重新定義此內(nèi)部類時(shí)赴精,會(huì)發(fā)生什么呢佩捞?也就是說,內(nèi)部類可以被重載嗎蕾哟?這看起來似乎是個(gè)很有用的點(diǎn)子一忱,但是“重載”內(nèi)部類就好像它是外圍類的一個(gè)方法,其實(shí)并不起什么作用:


class Egg {
    private Yolk y;


    public Egg() {
        System.out.println("New Egg()");
        y = new Yolk();
    }

    protected class Yolk {
        public Yolk() {
            System.out.println("Egg.Yolk()");
        }
    }
}


public class BigEgg extends Egg {
    public static void main(String[] args) {
        new BigEgg();
    }

    public class Yolk {
        public Yolk() {
            System.out.println("BigEgg.Yolk()");
        }
    }
}

輸出結(jié)果為:

New Egg()
Egg.Yolk()

缺省的構(gòu)造器是編譯器自動(dòng)生成的谭确,這里是調(diào)用基類的缺省構(gòu)造器帘营。你可能認(rèn)為既然創(chuàng)建了BigEgg 的對(duì)象,那么所使用的應(yīng)該是被“重載”過的Yolk逐哈,但你可以從輸出中看到實(shí)際情況并不是這樣的芬迄。

這個(gè)例子說明,當(dāng)你繼承了某個(gè)外圍類的時(shí)候昂秃,內(nèi)部類并沒有發(fā)生什么特別神奇的變化禀梳。這兩個(gè)內(nèi)部類是完全獨(dú)立的兩個(gè)實(shí)體,各自在自己的命名空間內(nèi)肠骆。當(dāng)然算途,明確地繼承某個(gè)內(nèi)部類也是可以的:

class Egg2 {
    private Yolk y = new Yolk();


    public Egg2() {
        System.out.println("New Egg2()");
    }

    public void insertYolk(Yolk yy) {
        y = yy;
    }

    public void g() {
        y.f();
    }

    protected class Yolk {
        public Yolk() {
            System.out.println("Egg2.Yolk()");
        }


        public void f() {
            System.out.println("Egg2.Yolk.f()");
        }
    }
}


public class BigEgg2 extends Egg2 {
    public BigEgg2() {
        insertYolk(new Yolk());
    }

    public static void main(String[] args) {
        Egg2 e2 = new BigEgg2();
        e2.g();
    }

    public class Yolk extends Egg2.Yolk {
        public Yolk() {
            System.out.println("BigEgg2.Yolk()");
        }


        public void f() {
            System.out.println("BigEgg2.Yolk.f()");
        }
    }
}

輸出結(jié)果為:

Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()
BigEgg2.Yolk.f()

現(xiàn)在BigEgg2.Yolk 通過extends Egg2.Yolk 明確地繼承了此內(nèi)部類,并且重載了其中的方法蚀腿。Egg2insertYolk()方法使得BigEgg2 將它自己的Yolk 對(duì)象向上轉(zhuǎn)型嘴瓤,然后傳遞給引用y。所以當(dāng)g()調(diào)用y.f()時(shí)莉钙,重載后的新版的f()被執(zhí)行廓脆。第二次調(diào)用Egg2.Yolk()BigEgg2.Yolk 的構(gòu)造器調(diào)用了其基類的構(gòu)造器〈庞瘢可以看到在調(diào)用g()的時(shí)候狞贱,新版的f()被調(diào)用了。


內(nèi)部類的繼承問題(thinking in java 3th p294)

因?yàn)閮?nèi)部類的構(gòu)造器要用到其外圍類對(duì)象的引用蜀涨,所以在你繼承一個(gè)內(nèi)部類的時(shí)候瞎嬉,事情變得有點(diǎn)復(fù)雜。問題在于厚柳,那個(gè)“秘密的”外圍類對(duì)象的引用必須被初始化氧枣,而在被繼承的類中并不存在要聯(lián)接的缺省對(duì)象。要解決這個(gè)問題别垮,需使用專門的語法來明確說清它們之間的關(guān)聯(lián):


class WithInner {
    class Inner {
        Inner() {
            System.out.println("this is a constructor in WithInner.Inner");
        }

        ;
    }
}


public class InheritInner extends WithInner.Inner {
    // ! InheritInner() {} // Won't compile
    InheritInner(WithInner wi) {
        wi.super();
        System.out.println("this is a constructor in InheritInner");
    }


    public static void main(String[] args) {
        WithInner wi = new WithInner();
        InheritInner ii = new InheritInner(wi);
    }
}


輸出結(jié)果為:

this is a constructor in WithInner.Inner
this is a constructor in InheritInner

可以看到便监,InheritInner 只繼承自內(nèi)部類,而不是外圍類。但是當(dāng)要生成一個(gè)構(gòu)造器時(shí)烧董,缺省的構(gòu)造器并不算好毁靶,而且你不能只是傳遞一個(gè)指向外圍類對(duì)象的引用。此外逊移,你必須在構(gòu)造器內(nèi)使用如下語法:

enclosingClassReference.super();

關(guān)于Java回調(diào)函數(shù)

在Java中预吆,通常就是編寫另外一個(gè)類或類庫的人規(guī)定一個(gè)接口,然后你來實(shí)現(xiàn)這個(gè)接口胳泉,然后把這個(gè)接口的一個(gè)對(duì)象作為參數(shù)傳給別人的程序拐叉,別人的程序必要時(shí)就會(huì)通過那個(gè)接口來調(diào)用你編寫的函數(shù),執(zhí)行后續(xù)的一些方法,。


public class CallBack {

    public static void main(String[] args) {
        CallBack callBack = new CallBack();
        callBack.toDoSomethings(100, new CallBackInterface() {
            public void execute() {
                System.out.println("我的請(qǐng)求處理成功了");
            }
        });

    }

    public void toDoSomethings(int a, CallBackInterface callBackInterface) {
        long start = System.currentTimeMillis();
        if (a > 100) {
            callBackInterface.execute();
        } else {
            System.out.println("a < 100 不需要執(zhí)行回調(diào)方法");
        }
        long end = System.currentTimeMillis();
        System.out.println("該接口回調(diào)時(shí)間 : " + (end - start));
    }
}
public interface CallBackInterface {

    void execute();
}

Java回調(diào)的實(shí)現(xiàn),是不是就是基于匿名內(nèi)部類實(shí)現(xiàn)的呢?答案是肯定的.

Java里的回調(diào),可以說是匿名內(nèi)部類精彩表演,優(yōu)美的編碼風(fēng)格,真是讓人陶醉~

本文部分源代碼


參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扇商,一起剝皮案震驚了整個(gè)濱河市凤瘦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌案铺,老刑警劉巖蔬芥,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異控汉,居然都是意外死亡笔诵,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門暇番,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嗤放,“玉大人思喊,你說我怎么就攤上這事壁酬。” “怎么了恨课?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵舆乔,是天一觀的道長。 經(jīng)常有香客問我剂公,道長希俩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任纲辽,我火速辦了婚禮颜武,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拖吼。我一直安慰自己鳞上,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布吊档。 她就那樣靜靜地躺著篙议,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鬼贱,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天移怯,我揣著相機(jī)與錄音,去河邊找鬼这难。 笑死舟误,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雁佳。 我是一名探鬼主播脐帝,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼糖权!你這毒婦竟也來了堵腹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤星澳,失蹤者是張志新(化名)和其女友劉穎疚顷,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體禁偎,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡腿堤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了如暖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片笆檀。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖盒至,靈堂內(nèi)的尸體忽然破棺而出酗洒,到底是詐尸還是另有隱情,我是刑警寧澤枷遂,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布樱衷,位于F島的核電站,受9級(jí)特大地震影響酒唉,放射性物質(zhì)發(fā)生泄漏矩桂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一痪伦、第九天 我趴在偏房一處隱蔽的房頂上張望侄榴。 院中可真熱鬧,春花似錦网沾、人聲如沸癞蚕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涣达。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間度苔,已是汗流浹背匆篓。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寇窑,地道東北人鸦概。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像甩骏,于是被迫代替她去往敵國和親窗市。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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