JAVA 類總結

來源:互聯網
上載者:User

標籤:表達   文法   產生   parameter   var   hang   abs   target   同名   

JAVA 類總結

最近看了遍java內部類相關的一些內容,做一些總結。與個人部落格 zhiheng.me 同步發布,標題: JAVA 類總結。

頂級類與嵌套類

定義在某個類(或介面,下同)內部的類,稱為嵌套類(nested class),相應的,其所在的類稱之為該類的外圍類(enclosing class)或包裹類。

非嵌套類稱為頂級類(top-level class),一個 .java 檔案中可以有若干個頂級類(含抽象類別和介面),但只能有一個被 public 修飾的類,且該類必須和 .java 檔案同名。

頂級類的存取修飾詞只能是 public 和包存取權限(預設許可權,無修飾符)。

嵌套類可看作是外圍類的一個成員,因此其修飾符可以是 public 、protected 、包存取權限和 private 。

嵌套類沒有層次限制,可以在嵌套類裡面在定義類,成為嵌套類中的嵌套類。

嵌套類分為兩種,一種是靜態(用 static 關鍵字修飾)稱為靜態嵌套類(static nested class);一種是非靜態,稱為內部類(inner class)。

註:在《Think in Java》一書中,作者將內部類定義為“將一個類定義在另一個類的定義內部,則這個類就是內部類”,因此,他將靜態嵌套類視為內部類的一種。而本文使用了 java 官方文檔中的定義。

內部類一般直接定義在外部類(outer class)中,就像該類的一個成員一樣,我們把這樣的內部類稱為成員內部類(member inner class)。即不在構造器、方法、語句塊中定義的內部類為成員內部類。

除成員內部類外還有另外兩種較特殊的內部類:局部內部類(local class)和匿名內部類(anonymous class)。

嵌套類位元組碼檔案命名

嵌套類經編譯後會自動產生獨立的位元組碼檔案(.class),其命名格式:

外部類名稱+\$+[該種類同名類中該類順序]+[內部類名稱]

以下代碼(檔案名稱:Outer.java)中含有靜態類 Static 、成員內部類 Inner 、局部類 Local 、實現 Anonymous 介面的匿名類以及定義在該源檔案中的介面 Anonymous 。

 

package thinkinjava; public class Outer {     public static class Static{}     public class Inner {}     {        class Local{};    }     Anonymous anonymous = new Anonymous(){};} interface Anonymous {}

編譯後形成了如下6個 .class 位元組碼檔案。頂級類 Outer 和 Anonymous 都被編譯成同名的 class 檔案,靜態嵌套類 Static 和成員內部類 Inner 被編譯成了 Outer\$Static.class 和 Outer\$Inner.class ,因為成員類不能同名,所以也就沒有同名類順序。局部類 Local 編譯後的檔案名稱是 Outer\$1Local.class ,因為 Outer 類中只有一個名為 Local 的局部類,因此,其順序是1。匿名類沒有名稱,所以編譯後的檔案名稱是 Outer\$1.class ,1表示該類是 Outer 類中第一個匿名類。

Anonymous.classOuter$1.classOuter$1Local.classOuter$Inner.classOuter$Static.classOuter.class
靜態嵌套類
public class OuterClass{    public static class NestClass{}}

靜態嵌套類因為是靜態,因此從本質上來說它和外部類的關係更像是類與包(package)的關係。在其他類中引用使用的時候需要加上外部類限定: OuterClass.NestClass 。

  1. 與靜態方法一樣,靜態嵌套類中不能訪問外部類的非靜態成員和非靜態方法(不管是public還是private的);
  2. 靜態嵌套類的執行個體化(instantiate)無需事先執行個體化外部類,因為靜態嵌套類是與外部類直接相關聯的,而非與外部類的執行個體(instance)相關聯。
內部類

內部類是非靜態,因此內部類是與外部類的執行個體相關聯的。在執行個體化內部類時,必須先行執行個體化外部類,再通過外部類的執行個體來建立內部類的執行個體:

OuterClass outObject = new OuterClass();OuterClass.InnerClass innerObject = outerObject.new InnerClass();
  1. 內部類中不能有 static 關鍵字修飾的靜態成員(塊、欄位、方法、介面等),除非該成員是靜態常量。所以,內部類中的靜態成員必須是同時使用 final 關鍵字修飾的欄位。
  2. 內部類可以訪問外部類的任何成員(包括構造器),不管是公有的還是私人的,靜態還是非靜態。同樣,外部類也可以訪問到內部類的所有成員。
遮蔽(Shadowing)

定義在內部類或成員方法內的欄位或參數,如果和外部範圍內的某個成員變數定義同名,那麼外部的定義將被遮蔽,此時無法在內部範圍內僅通過名字訪問到外部的成員。以下是摘自 Java Tutorial 中的一個例子:

public class ShadowTest {     public int x = 0;     class FirstLevel {         public int x = 1;         void methodInFirstLevel(int x) {            System.out.println("x = " + x);            System.out.println("this.x = " + this.x);            System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);        }    }     public static void main(String... args) {        ShadowTest st = new ShadowTest();        ShadowTest.FirstLevel fl = st.new FirstLevel();        fl.methodInFirstLevel(23);    }}// 輸出如下// x = 23// this.x = 1// ShadowTest.this.x = 0
局部內部類

局部類是定義在某個塊(block)中的類。即定義在構造器、方法、迴圈體、分支結構(if 子句)中的類。

  1. 同局部變數,局部類不能用public,private,protected,static修飾,但可以被final或者abstract修飾。
  2. 局部類是內部類,因此可以訪問其外部類的成員。但局部類的範圍在塊內,所以外部類無法訪問到局部內部類。

局部類屬於塊的範圍,因此可以訪問局部變數(包括形參),但是只能訪問用 final 修飾的局部變數。

在 Java SE 8 之後,局部類可以訪問 effectively final 的局部變數和非 final 的形參了,effectively final 的變數沒有 final 修飾但在初始化後從未改變過值。 “A variable or parameter whose value is never changed after it is initialized is effectively final” 。

 

匿名類

匿名類,顧名思義就是沒有名稱的類,沒有名稱也就無法在其他地方引用和執行個體化,當然也就沒有構造器。匿名類在定義的同時會執行個體化本身(匿名類只執行個體化這一次)。

匿名類的定義從形式上看更像是一種運算式,也就是類的定義出現在一個運算式中。從文法形式上看,匿名類的定義像是調用了一個構造器。以下是幾種匿名類的例子:

public class Test {    InterfaceA a = new InterfaceA() {};//成員匿名類    public static void main(String[] args){        InterfaceA a = new InterfaceA() {};//局部匿名類        //以上兩種是通過實現介面實現匿名類,稱為介面式匿名類,也可以通過繼承類實現        Test test = new Test(){};//繼承式匿名類        //還可以是位於參數上        new Thread(new Runnable() {            @Override            public void run() {            }        }).start();//屬於局部匿名類一種    }    private interface InterfaceA{}} 

匿名類不能使用任何關鍵字和存取控制符,匿名類和局部類訪問規則一樣,只不過內部類顯式的定義了一個類,然後通過new的方式建立這個局部類執行個體,而匿名類直接new一個類執行個體。

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.