Java內部類學習總結

來源:互聯網
上載者:User

標籤:java

目錄

  • 目錄
  • 概述
  • 非靜態內部類
    • 從外部類的非靜態方法中執行個體化內部類
    • 從外部類的靜態方法中執行個體化內部類
    • 內部類的this引用
  • 靜態內部類
    • 從外部類的非靜態方法中執行個體化靜態內部類
    • 從外部類靜態方法中執行個體化靜態內部類
  • 匿名內部類
  • 方法內部類

概述

最近學習python,發現python是支援多繼承的,這讓我想起Java是通過內部類實現的這套機制。這篇文章不是講如何通過內部類實現多繼承,而是總結一下內部類的類型和使用方法。

Java內部類分為:

  • 非靜態內部類
  • 靜態內部類
  • 局部內部類
  • 匿名內部類

內部類在Android源碼中被大量的使用,先介紹一下這四種內部類的共同點:

  1. 內部類仍然是一個獨立的類,在編譯之後內部類會被編譯成獨立的.class檔案,但是前面冠以外部類的類名和$符號。
  2. 內部類不能用普通的方式訪問。內部類是外部類的一個成員,因為內部類可以自由的訪問外部類的成員,包括private成員。
  3. 內部類聲明為靜態,就不能隨意的訪問外部類的成員變數了,此時內部類只能訪問到外部類的靜態成員變數。

接下來,分別介紹一下這幾種內部類。

非靜態內部類

當一個類作為另一個類的非靜態成員時,則這個類就是一個非靜態內部類。
建立非靜態內部類的範例程式碼如下:

class OutClass {    class InnerClass {}}

當我們用javac去編譯的時候,發現產生了兩個.class檔案:OutClass.class和OutClass$InnerClass.class。如所示:

從外部類的非靜態方法中執行個體化內部類

在外部類中訪問內部類是很容易的,直接建立內部類對象,然後通過對象執行個體調用類內的方法即可。範例程式碼如下:

public class OutClass {    private static int a = 0;    public void makeInner() {        InnerClass inClass = new InnerClass();        inClass.seeOuter();    }    public static void main(String[] args) {        OutClass oClass = new OutClass();        oClass.makeInner();    }    class InnerClass {        public void seeOuter() {            System.out.println(a);            a++;        }    }}

運行結果如下:

0
從外部類的靜態方法中執行個體化內部類

在外部類中訪問內部類是比較簡單的,可以直接new出內部類對象,但是如果想在外部類的外部使用內部類,接不能直接new內部類名的方式了,而是需要如下方式:

OutClass.InnerClass innerClass = new OutClass().new InnerClass();

也就是說,在外部調用非靜態內部類,需要先執行個體化外部類,然後通過外部類對象再去執行個體化內部類。範例程式碼如下:

public class OutClass {    private static int a = 0;    public void makeInner() {        InnerClass inClass = new InnerClass();        inClass.seeOuter();    }    public static void main(String[] args) {        OutClass oClass = new OutClass();        oClass.makeInner();        OutClass.InnerClass innerClass = new OutClass().new InnerClass();        innerClass.seeOuter();    }    class InnerClass {        public void seeOuter() {            System.out.println(a);            a++;        }    }}

運行結果:

01
內部類的this引用

普通的類可以使用this引用當前的對象,內部類也是如此。但是假若內部類想引用外部類當前的對象呢?可以使用如下方式:

外部類名.this

範例程式碼如下:

public class OutClass {    private static int a = 0;    public void makeInner() {        InnerClass inClass = new InnerClass();        inClass.seeOuter();    }    public static void main(String[] args) {        OutClass oClass = new OutClass();        oClass.makeInner();        OutClass.InnerClass innerClass = new OutClass().new InnerClass();        innerClass.seeOuter();    }    class InnerClass {        public void seeOuter() {            System.out.println(this);            System.out.println(OutClass.this);        }    }}
靜態內部類

上面介紹了非靜態內部類,接下來我們學習神馬是靜態內部類。

靜態內部類就是在外部類中扮演一個靜態成員的角色,建立靜態內部類和建立非靜態內部類的形式很相似,只是class前面多了一個static修飾符。

注意,外部類是不可能使用static修飾符進行修飾的。

範例程式碼如下:

class OutClass {    static class InnerClass {    }}

用javac命令編譯一下,可以看到一樣都是有兩個.class檔案,如所示:

從外部類的非靜態方法中執行個體化靜態內部類

從外部類中訪問靜態內部類,和在外部類中訪問非靜態內部類是一樣的。但是,需要注意一點,此時靜態內部類只能訪問外部類的靜態成員,無法訪問非靜態成員了。

範例程式碼如下:

public class OutClass {    private static int a = 0;    private int b = 1;    public void makeInner() {        InnerClass inClass = new InnerClass();        inClass.seeOuter();    }    public static void main(String[] args) {        OutClass oClass = new OutClass();        oClass.makeInner();    }    static class InnerClass {        public void seeOuter() {            System.out.println(this);            System.out.println(a);            // System.out.println(b);        }    }}

執行結果如下:

OutClass$InnerClass@79a3400
從外部類靜態方法中執行個體化靜態內部類

注意:
因為靜態內部類是外部類的靜態成員,而靜態成員是跟類綁定,而不是跟類執行個體化的對象綁定。所以,在外部類的靜態方法中執行個體化內部類,是不需要先執行個體化外部類的。

範例程式碼如下:

public class OutClass {    private static int a = 0;    private int b = 1;    public void makeInner() {        InnerClass inClass = new InnerClass();        inClass.seeOuter();    }    public static void main(String[] args) {        OutClass oClass = new OutClass();        oClass.makeInner();        OutClass.InnerClass inClass = new OutClass.InnerClass();        inClass.seeOuter();    }    static class InnerClass {        public void seeOuter() {            System.out.println(this);            System.out.println(a);            // System.out.println(b);        }    }}
匿名內部類

匿名內部類在Android應用開發中簡直是泛濫,各種listener對象的實現很多都是通過匿名內部類。

匿名內部類從名字上就可以知道這是代表沒有類名的內部類,通常用來簡化代碼。

相信寫Java的同學都使用過線程,那Thread的時候我們可以傳一個Runnable對象,也可以傳一個匿名內部類。範例程式碼如下:

public class OutClass {    public void testAnonymousClass() {        Thread t = new Thread(new Runnable() {            @Override            public void run() {                for (int i = 0; i < 10; i ++) {                    System.out.println(i);                    try {                        Thread.sleep(500);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        });        t.start();        System.out.println("another thread is running...");    }    public static void main(String[] args) {        OutClass oClass = new OutClass();        oClass.testAnonymousClass();    }}

執行結果如下:

another thread is running...0123456789
方法內部類

方法內部類顧名思義,就是將類放在方法中,然後它的範圍也是方法的範圍。

然而,我認為方法內部類並沒有什麼卵用,所以這裡不講了,就是這麼任性。

Java內部類學習總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.