Java內(nèi)部類總結(jié)

什么是內(nèi)部類

如果一個類定義在另一個類的內(nèi)部意推,那么這個類就是內(nèi)部類∩后埃可以通過public菊值,protected,private修飾符來控制內(nèi)部類的可見性育灸。同時腻窒,內(nèi)部類也可以被聲明為abstract類型,供其他類繼承和擴展磅崭。

內(nèi)部類是一個編譯時的概念儿子,一旦編譯成功,內(nèi)部類和外部類就是兩個完全不同的類砸喻。例如柔逼,對于一個外部類Outer,在其中定義一個內(nèi)部類Inner恩够,編譯完成后會生成Outer.classOuter$Inner.class兩個class文件卒落。所以內(nèi)部類的成員變量和方法名可以和外部類相同。

內(nèi)部類用法

按照內(nèi)部類的用法蜂桶,可以將內(nèi)部類分為成員內(nèi)部類儡毕,局部內(nèi)部類,匿名內(nèi)部類以及靜態(tài)內(nèi)部類。

成員內(nèi)部類

成員內(nèi)部類就是在外圍類的內(nèi)部直接定義一個類腰湾±资眩可以通過public,protected费坊,private修飾符來控制其可見性倒槐。在創(chuàng)建內(nèi)部類的時候,可以直接創(chuàng)建內(nèi)部類附井,也可以讓內(nèi)部類繼承某個基類或者接口讨越。如下所示。

1. 直接創(chuàng)建內(nèi)部類
public class Parcel1 {

    private class Contents {
        private String content = "goods";
        public String contents() {
            return content;
        }
    }

    public class Destination {
        private String dest;
        Destination(String dest) {
            this.dest = dest;
        }

        public String dest() {
            return dest;
        }
    }

    public void ship1(String dest) {
        Contents c = new Contents();
        Destination d = new Destination(dest);
        System.out.println("content: " + c.contents() + ", destination: " + d.dest());
    }

    public static void ship2(String dest) {
        Parcel1 p = new Parcel1();
        Contents c = p.new Contents();
        Destination d = p.new Destination("dest2");
        System.out.println("content: " + c.contents() + ", destination: " + d.dest());
    }

    public static void main(String[] args) {
        Parcel1 p = new Parcel1();
        p.ship1("dest1");

        Parcel1.ship2("dest2");
    }
}

在上面例子中永毅,ContentsDestination都定義在Parcel1類的內(nèi)部把跨,它們都是public的,所以通過其他類也可以訪問到沼死。通過ship1方法和ship2方法着逐,我們可以看到創(chuàng)建內(nèi)部類對象的兩種方式。

  • 在外部類的非靜態(tài)方法創(chuàng)建內(nèi)部類對象

    這種方式和使用普通類沒有什么區(qū)別意蛀∷时穑可以直接通過new InnerClass()的方式來創(chuàng)建內(nèi)部類對象。如ship1方法所示县钥。

  • 在外部類的靜態(tài)方法或者其他類中創(chuàng)建內(nèi)部類對象

    在外部類的靜態(tài)方法或者其他類創(chuàng)建內(nèi)部類對象時秀姐,我們必須首先創(chuàng)建外部類對象outterObj,然后通過outterObj.new InnerClass()的方式來創(chuàng)建內(nèi)部類對象魁蒜。如ship2方法所示囊扳。

2.通過實現(xiàn)接口/繼承基類創(chuàng)建內(nèi)部類

除了直接創(chuàng)建內(nèi)部類,我們還可以讓內(nèi)部類實現(xiàn)某個接口或者繼承某個基類兜看。這樣蔽介,我們在使用內(nèi)部類對象的時候眯杏,可以將其向上轉(zhuǎn)型為對其基類或者接口的引用党窜。這樣能夠方便地隱藏內(nèi)部類實現(xiàn)細節(jié)并屏蔽類型差異且警。如下所示。

public interface IContents {
    String contents();
}
public interface IDestination {
    String dest();
}
public class Parcel2 {

    private class Contents implements IContents{
        private String content = "goods";

        @Override
        public String contents() {
            return content;
        }
    }

    private class Destination implements IDestination{
        private String dest;
        Destination(String dest) {
            this.dest = dest;
        }

        @Override
        public String dest() {
            return dest;
        }
    }

    public Destination destination(String dest) {
        return new Destination(dest);
    }

    public Contents contents() {
        return new Contents();
    }

    public static void main(String[] args) {
        Parcel2 p = new Parcel2();
        IContents c = p.contents();
        IDestination d = p.destination("dest1");
        System.out.println("contents: " + c.contents() + ", destination: " + d.dest());
    }
}

這里弧轧,內(nèi)部類DestinationContents分別實現(xiàn)了接口IDestinationIContents雪侥,我們在訪問內(nèi)部類對象的時候,可以通過IDestinationIContents的引用來訪問內(nèi)部類對象精绎,而不再需要關心內(nèi)部類對象的具體類型速缨。因此,我們可以把DestinationContents設置為private類型代乃。設置為private類型后旬牲,在其他類中無法直接創(chuàng)建內(nèi)部類對象仿粹,所以需要在外部類中新增destinationcontent方法來獲取內(nèi)部類對象。

訪問外對象成員

內(nèi)部類可以無縫地訪問外部類對象的所有成員原茅,因為當創(chuàng)建一個內(nèi)部類對象的時候吭历,內(nèi)部類對象會隱式地持有一個指向外部類對象的引用,通過這個引用來訪問外部類的所以成員變量及方法擂橘。當然晌区,也可以訪問外部類對象本身。關于這點通贞,我們可以直接通過反編譯內(nèi)部類的class文件來驗證朗若。我們首先使用javac命令編譯前面的Parcel1,編譯之后昌罩,我們看到目錄下生成了三個class文件捡偏。

Parcel1$1.class
Parcel1$Contents.class
Parcel1$Destination.class

這也驗證了內(nèi)部類是一個編譯時的概念,在編譯完成后峡迷,內(nèi)部類和外部類就是兩個完全獨立的類了。通過IntelliJ IDEA我們可以查看反編譯后的class文件你虹,我們查看下Parcel1$Contents.class文件绘搞,代碼如下所示。

class Parcel1$Contents {
    private String content;

    private Parcel1$Contents(Parcel1 var1) {
        this.this$0 = var1;
        this.content = "goods";
    }

    public String contents() {
        return this.content;
    }
}

可以看到傅物,編譯器為我們做了很多工作夯辖,它會自動生成一個內(nèi)部類的構(gòu)造方法,這個方法傳入的是外部類對象的一個引用董饰,在內(nèi)部類中蒿褂,然后在內(nèi)部類中還會一定一個成員變量this$0來存儲外部類對象的引用。所以卒暂,我們在創(chuàng)建一個內(nèi)部類對象之前啄栓,必須首先要創(chuàng)建外部類對象。

持有外部類對象的引用是內(nèi)部類最有用的一個特性也祠,通過這種方式昙楚,我們可以把內(nèi)部類作為訪問外部類的一個窗口。所有內(nèi)部類(靜態(tài)內(nèi)部類除外)在創(chuàng)建的時候都會持有外部類對象的應用诈嘿,所以在創(chuàng)建內(nèi)部類對象的時候堪旧,我們必須先創(chuàng)建一個外部類對象。而不能直接通過 new InnerClass的方式來創(chuàng)建內(nèi)部類對象奖亚。例如淳梦,下面通過內(nèi)部類來實現(xiàn)一個迭代器。

public interface Selector {
    boolean end();
    Object current();
    void next();
}
public class Sequence {

    private Object[] items;
    private int next = 0;

    public Sequence(int size) {
        items = new Object[size];
    }

    public void add(Object x) {
        if (next<items.length) {
            items[next++] = x;
        }
    }

    private class SequenceSelector implements Selector {

        private int i=0;

        @Override
        public boolean end() {
            return i==items.length;
        }

        @Override
        public Object current() {
            return items[i];
        }

        @Override
        public void next() {
            if (i < items.length) {
                i++;
            }
        }
    }

    public Selector selector() {
        return new SequenceSelector();
    }

    public static void main(String[] args) {
        Sequence sequence = new Sequence(20);
        for (int i=0;i<20;i++) {
            sequence.add(i);
        }
        Selector selector = sequence.selector();
        while (!selector.end()) {
            System.out.println(selector.current());
            selector.next();
        }
    }
}

如果想要在內(nèi)部類中訪問外部類對象本身昔字,可以通過OutterClass.this來訪問爆袍。

局部內(nèi)部類

除了可以定義成員內(nèi)部類(也就是在外部類中直接定義內(nèi)部類)外,我們還可以在方法或者局部作用域內(nèi)定義內(nèi)部類。

1.在方法內(nèi)部定義內(nèi)部類
public class Parcel3 {

    public IDestination destination(String dest) {
        class Destination implements IDestination{
            private String dest;
            Destination(String dest) {
                this.dest = dest;
            }

            @Override
            public String dest() {
                return dest;
            }
        }
        return new Destination(dest);
    }

    public IContents contents() {
        class Contents implements IContents{
            private String content = "goods";

            @Override
            public String contents() {
                return content;
            }
        }
        return new Contents();
    }

    public static void main(String[] args) {
        Parcel3 p = new Parcel3();
        IContents c = p.contents();
        IDestination d = p.destination("dest1");
        System.out.println("contents: " + c.contents() + ", destination: " + d.dest());
    }
}

這里的DestinationContents類分別定義在了方法destinationcontent內(nèi)部螃宙,所以他們只能在所定義的方法內(nèi)部訪問蛮瞄。方法之外的其他地方無法訪問該內(nèi)部類。

2.在代碼塊定義內(nèi)部類

除了可以在方法中定義內(nèi)部類外谆扎,我們也可以直接在代碼塊中定義內(nèi)部類挂捅,如下所示。

public class Parcel4 {

    public IDestination destination(String dest) {
        class Destination implements IDestination{
            private String dest;
            Destination(String dest) {
                this.dest = dest;
            }

            @Override
            public String dest() {
                return dest;
            }
        }
        return new Destination(dest);
    }

    public IContents contents(boolean hasContent) {
         if (hasContent) {
             class Contents implements IContents {
                 private String content = "goods";

                 @Override
                 public String contents() {
                     return content;
                 }
             }
             return new Contents();
         }
         return null;
    }

    public static void main(String[] args) {
        Parcel4 p = new Parcel4();
        IContents c = p.contents(true);
        IDestination d = p.destination("dest1");
        System.out.println("content: " + c.contents() + ", destination: " + d.dest());
    }
}

可以看到Contents的定義放在了if語句內(nèi)部堂湖,這就意味著闲先,在if語句外,我們無法使用該內(nèi)部類无蜂。

雖然Contents定義在了if代碼塊內(nèi)部伺糠,但是這并不代表該類的創(chuàng)建是有條件的,因為內(nèi)部類是在編譯器生成的斥季,編譯完成后训桶,該類和外部類沒有區(qū)別,只是作用域不同罷了酣倾。

局部內(nèi)部類除了作用域不同外舵揭,具有和成員內(nèi)部類一樣的特性,局部內(nèi)部類也可以實現(xiàn)某個接口或者繼承某個基類躁锡,也可以直接訪問外部類對象中的所有成員和方法午绳。但是局部內(nèi)部類不能有訪問說明符,因為他只能在方法或者代碼塊內(nèi)部訪問映之。

訪問本地變量

當局部內(nèi)部類引用本地變量時拦焚,本地變量必須是final類型或者實際上是final類型「苁洌看下面的例子赎败。

public class Parcel7 {

    public IDestination destination(String localDest) {
        class Destination implements IDestination{
            @Override
            public String dest() {
                return localDest;
            }
        }
        return new Destination();
    }

    public IContents contents(boolean hasContent) {
        if (hasContent) {
            class Contents implements IContents {
                private String content = "goods";

                @Override
                public String contents() {
                    return content;
                }
            }
            return new Contents();
        }
        return null;
    }

    public static void main(String[] args) {
        Parcel7 p = new Parcel7();
        IContents c = p.contents(true);
        IDestination d = p.destination("dest1");
        System.out.println("content: " + c.contents() + ", destination: " + d.dest());
    }
}

在上面的例子中,在Destination是一個局部內(nèi)部類蠢甲,并且在Destinationdest方法中直接引用了外部類destination方法中傳入的localDest參數(shù)螟够。這Java8之前,這段代碼在編譯時會直接報錯峡钓,報錯提示如下所示(用Java7編譯)妓笙。

java: 從內(nèi)部類中訪問本地變量localDest; 需要被聲明為最終類型

也就是說localDest必須聲明為final類型,為什么要聲明為final類型呢能岩?原因是本地變量的生命周期在方法執(zhí)行完成的時候就結(jié)束了寞宫,而內(nèi)部類的生命周期大多數(shù)啊情況下會比本地變量的生命周期要長。如果本地變量被回收拉鹃,那么在內(nèi)部類執(zhí)行到訪問本地變量的代碼時就會導致空指針問題辈赋。所以鲫忍,為了解決這個問題,在創(chuàng)建內(nèi)部類的時候钥屈,會在內(nèi)部類中以成員變量的形式對本地變量做一個備份悟民,這個是編譯器自動幫我們完成的。關于這點篷就,我們可以通過反編譯Parcel7類來找到答案射亏。

我們通過javac命令編譯Parcel7類,編譯完成后會產(chǎn)生如下三個.class文件竭业。

Parcel7$1Contents.class
Parcel7$1Destination.class
Parcel7.class

然后使用javap命令對Parcel7$1Destination.class文件進行反編譯智润。

javap -private Parcel7$1Destination.class

反編譯結(jié)果如下所示。

class Parcel7$1Destination implements IDestination {
  final java.lang.String val$localDest;
  final Parcel7 this$0;
  Parcel7$1Destination();
  public java.lang.String dest();
}

可以看到未辆,在內(nèi)部類中多了一個val$localDest的成員變量窟绷,這個成員變量就是內(nèi)部類Destination中用來對Parcel7.destination方法中傳入的localDest做備份的。同時也可以看到val$localDest是final類型的咐柜。這意味著兼蜈,如果我們想在內(nèi)部類內(nèi)對localDest做修改,也是不允許的拙友。那為什么本地變量要定義成final類型呢饭尝,先來看看final類型的特點。如果一個變量被聲明為final類型献宫,它有如下特點。

  1. 當final修飾基本數(shù)據(jù)類型的變量時实撒,這個變量在初始化時就會被賦值姊途,并且初始化完成之后其值就不能再被改變了。
  2. 當final修飾引用類型的變量時知态,這個變量在初始化時就會被賦值捷兰,并且初始化完成之后其值就不能再被改變,但是該變量指向?qū)ο蟮亩褍?nèi)存的值是可以改變的负敏。

如果當內(nèi)部類引用本地變量的時候贡茅,不把本地變量聲明為final類型,在內(nèi)部類或者外部類的方法中對本地變量做修改后其做,很容易造成理解上的混淆和代碼行為的錯亂顶考,所以為了避免混淆和錯亂的問題,在內(nèi)部類引用本地變量的時候妖泄,需要把本地變量聲明為final類型驹沿。這樣內(nèi)部類和方法中的本地變量值就可以始終保持一致。

在Java8之后蹈胡,不再需要強制將本地變量聲明為final類型渊季,所以上面的代碼在Java8下編譯的時候朋蔫,不會報錯也可以正常執(zhí)行。但是却汉,如果我們想嘗試改變本地變量的值驯妄,編譯器還是會報錯。例如合砂,我們將destination做如下修改青扔。

public IDestination destination(String localDest) {
    class Destination implements IDestination{
        @Override
        public String dest() {
            return localDest;
        }
    }

    localDest = "dest2";
    System.out.println(localDest);
    return new Destination();
}

我們在方法內(nèi)重新對localDest變量進行賦值,然后編譯既穆,編譯器報錯如下所示赎懦。

java: 從內(nèi)部類引用的本地變量必須是最終變量或?qū)嶋H上的最終變量

所以,Java8雖然不再需要將本地變量強制聲明為final類型幻工,但是實際上還是要求本地變量時final類型励两。關于這點,我們可以查看Parcel7.class文件囊颅。

public class Parcel7 {
    public Parcel7() {
    }

    public IDestination destination(final String var1) {
        class Destination implements IDestination {
            Destination() {
            }

            public String dest() {
                return var1;
            }
        }

        return new Destination();
    }
    ……
}

可以看到当悔,如果在內(nèi)部類引用了本地變量,編譯器會自動將該本地變量轉(zhuǎn)變?yōu)閒inal類型踢代。

匿名內(nèi)部類

匿名內(nèi)部類本質(zhì)也屬于一種局部內(nèi)部類盲憎,它主要是用于某個類只需要創(chuàng)建一個對象,而不需要再使用的場景胳挎。饼疙。如下所示。

public class Parcel5 {

    public IDestination destination(String dest) {
        class Destination implements IDestination{
            private String dest;
            Destination(String dest) {
                this.dest = dest;
            }

            @Override
            public String dest() {
                return dest;
            }
        }
        return new Destination(dest);
    }

    public IContents contents() {
        return new IContents() {
            private String content = "goods";
            @Override
            public String contents() {
                return content;
            }
        };
    }

    public static void main(String[] args) {
        Parcel5 p = new Parcel5();
        IContents c = p.contents();
        IDestination d = p.destination("dest1");
        System.out.println("content: " + c.contents() + ", destination: " + d.dest());
    }
}

這里在創(chuàng)建Contents對象的時候慕爬,就使用到了匿名內(nèi)部類窑眯。之所以叫匿名內(nèi)部類,就是這個類沒有名字医窿,而是直接通過實現(xiàn)某個接口或者基類來創(chuàng)建一個對象磅甩,匿名內(nèi)部類的語法格式如下所示。

new SuperType(construction parameters){
  //inner class methods and data
}

其中SuperType可以是像IContents這樣的接口姥卢,也可以是一個類卷要。在Java中定義回調(diào)函數(shù)的時候,經(jīng)常會用到匿名內(nèi)部類独榴。例如僧叉,在創(chuàng)建一個子線程的時候,我們通常會給Thread的構(gòu)造方法傳遞一個實現(xiàn)了Runnable接口的匿名內(nèi)部類對象棺榔。

new Thread(new Runnable(){

  @Override
  public void run() {
    System.out.println("Thread");
  }
}).start();

上面的contents方法通過實現(xiàn)IContents接口創(chuàng)建了匿名內(nèi)部類對象彪标,默認使用了匿名內(nèi)部類的無參構(gòu)造器。在創(chuàng)建匿名內(nèi)部類對象的時候掷豺,也可以使用有參數(shù)的構(gòu)造器上捞烟,不過因為匿名內(nèi)部類是沒有名字的薄声,所以肯定不能在匿名內(nèi)部類里邊定義帶參數(shù)的構(gòu)造器。所以题画,如果想在創(chuàng)建匿名內(nèi)部類的時候默辨,使用帶參數(shù)的構(gòu)造器,必須要匿名內(nèi)部類的基類含有帶參數(shù)的構(gòu)造器苍息。如下所示缩幸。

public class BaseDestination {
    private String dest  = "";
    public BaseDestination (String dest) {
        this.dest = dest;
    }

    public String dest() {
        return dest;
    }
}
public class Parcel6 {

    public BaseDestination destination(String dest) {
        return new BaseDestination(dest) {
            @Override
            public String dest() {
                return super.dest();
            }
        };
    }

    public IContents contents() {
        return new IContents() {
            private String content = "goods";
            @Override
            public String contents() {
                return content;
            }
        };
    }

    public static void main(String[] args) {
        Parcel6 p = new Parcel6();
        IContents c = p.contents();
        BaseDestination d = p.destination("dest1");
        System.out.println("content: " + c.contents() + ", destination: " + d.dest());
    }
}

上面的例子中,我們通過繼承BaseDestination來創(chuàng)建了一個匿名內(nèi)部類對象竞思,在創(chuàng)建的時候表谊,我們使用了匿名內(nèi)部類基類的帶參構(gòu)造器。

由于匿名內(nèi)部類本質(zhì)上也是一種局部內(nèi)部類盖喷,它在訪問本地變量時也需要將本地變量聲明為final類型或者本地變量實際上符合final類型的特點爆办。

靜態(tài)內(nèi)部類

前面學習的成員內(nèi)部類,局部內(nèi)部類和匿名內(nèi)部類對象在創(chuàng)建的時候都會隱式地持有外部類對象的引用课梳,如果不想內(nèi)部類和外部類對象之間有聯(lián)系距辆,可以將內(nèi)部類聲明為static類型,這就是所謂的靜態(tài)內(nèi)部類暮刃。靜態(tài)內(nèi)部類對象不會持有外部類對象的引用跨算,所以在創(chuàng)建靜態(tài)內(nèi)部類對象的時候,并不需要事先創(chuàng)建外部類對象椭懊。由于沒有持有外部類對象的引用诸蚕,所以,在靜態(tài)內(nèi)部類中只能訪問外部類的靜態(tài)成員變量和靜態(tài)方法氧猬,而無法訪問非靜態(tài)成員變量和非靜態(tài)方法背犯。

靜態(tài)內(nèi)部類由于切斷了和外部類的聯(lián)系,所以它和外部類更加獨立狂窑。例如,我們在設計模式中經(jīng)常用到的構(gòu)建者模式桑腮,就是靜態(tài)內(nèi)部類的一種典型應用泉哈。如下所示。

public class Student {
    private String name = "";
    private int age;
    private String address = "";

    private Student(Builder builder) {
        name = builder.name;
        age = builder.age;
        address = builder.address;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getAddress() {
        return address;
    }

    public static Builder newBuilder(){
        return new Builder();
    }

    public static class Builder {
        private String name = "";
        private int age;
        private String address = "";

        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        public Builder setAge(int age) {
            this.age = age;
            return this;
        }

        public Builder setAddress(String address) {
            this.address = address;
            return this;
        }

        public Student build() {
            return new Student(this);
        }
    }
}
public class BuilderTest {
    public static void main(String[] args) {
        Student.Builder builder = Student.newBuilder();
        Student student = builder.setName("xxx")
            .setAge(18)
            .setAddress("China")
            .build();
        System.out.println("name: " + student.getName() + ", age: " + student.getAge() + ", address: " +student.getAddress() );
    }
}

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

那么Java為什么要使用內(nèi)部類呢破讨?通過內(nèi)部類的特點和用法丛晦,我們可以總結(jié)出以下原因。

  1. 內(nèi)部類定義在一個類的內(nèi)部提陶,通過內(nèi)部類我們可以訪問外部類的變量和方法烫沙,對外部類對象進行操作,作為訪問外部類的一個窗口隙笆。
  2. 內(nèi)部類可以對其他類隱藏可見性和實現(xiàn)細節(jié)锌蓄,保證內(nèi)部類的擴展性和隔離性升筏。
  3. 內(nèi)部類是實現(xiàn)多繼承的一種方式,每個內(nèi)部類都能獨立的繼承一個類或者實現(xiàn)若干個接口瘸爽,而不受外圍類和其他內(nèi)部類的限制您访,所以是實現(xiàn)多繼承的一種方案。
  4. 內(nèi)部類有一些有用的特性剪决,例如灵汪,當想要定義一個回調(diào)方法的時候,使用匿名內(nèi)部類能提供很大的便捷性柑潦。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末享言,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子渗鬼,更是在濱河造成了極大的恐慌览露,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乍钻,死亡現(xiàn)場離奇詭異肛循,居然都是意外死亡,警方通過查閱死者的電腦和手機银择,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門多糠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浩考,你說我怎么就攤上這事夹孔。” “怎么了析孽?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵搭伤,是天一觀的道長。 經(jīng)常有香客問我袜瞬,道長怜俐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任邓尤,我火速辦了婚禮拍鲤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘汞扎。我一直安慰自己季稳,他們只是感情好,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布澈魄。 她就那樣靜靜地躺著景鼠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪痹扇。 梳的紋絲不亂的頭發(fā)上铛漓,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天溯香,我揣著相機與錄音,去河邊找鬼票渠。 笑死逐哈,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的问顷。 我是一名探鬼主播昂秃,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼杜窄!你這毒婦竟也來了肠骆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤塞耕,失蹤者是張志新(化名)和其女友劉穎蚀腿,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扫外,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡莉钙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了筛谚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片磁玉。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖驾讲,靈堂內(nèi)的尸體忽然破棺而出蚊伞,到底是詐尸還是另有隱情,我是刑警寧澤吮铭,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布时迫,位于F島的核電站,受9級特大地震影響谓晌,放射性物質(zhì)發(fā)生泄漏掠拳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一纸肉、第九天 我趴在偏房一處隱蔽的房頂上張望溺欧。 院中可真熱鬧,春花似錦毁靶、人聲如沸胧奔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至胳泉,卻和暖如春拐叉,著一層夾襖步出監(jiān)牢的瞬間岩遗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工凤瘦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留宿礁,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓蔬芥,卻偏偏與公主長得像梆靖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子笔诵,可洞房花燭夜當晚...
    茶點故事閱讀 45,440評論 2 359

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

  • 概念介紹 內(nèi)部類在Java中返吻,可以將一個類定義在另一個類里面或者一個方法里面,這樣的類稱為內(nèi)部類乎婿。內(nèi)部類是一種非常...
    niaoge2016閱讀 657評論 0 1
  • 一测僵、內(nèi)部類有幾種? 內(nèi)部類分為成員內(nèi)部類谢翎、靜態(tài)嵌套類捍靠、方法內(nèi)部類、匿名內(nèi)部類森逮。幾種內(nèi)部類的共性:A榨婆、內(nèi)部類仍然是一...
    yekai閱讀 294評論 0 0
  • 前言 隨著工作經(jīng)驗的增加,越發(fā)感覺到基礎的重要性吊宋,所以最近上下班地鐵上都在看一些基礎的東西纲辽,前幾天看了拭心大哥講的...
    實例波閱讀 511評論 0 1
  • 內(nèi)部類分為四類:成員內(nèi)部類、局部(作用域)內(nèi)部類璃搜、匿名內(nèi)部類拖吼、靜態(tài)內(nèi)部類。 內(nèi)部類大比拼 成員內(nèi)部類 就像一個成員...
    果女郎閱讀 392評論 0 1
  • 前言 這幾天趁著時間多多这吻,回顧并總結(jié)出來超全面的Java內(nèi)部類知識吊档;Java內(nèi)部類老實說我們在開發(fā)的時候用的不多,...
    JTravler閱讀 748評論 0 1