1. 程式人生 > >Java中內部類的騷操作

Java中內部類的騷操作

 

10.1 如何定義內部類

如程式碼10.1-1 所示

public class Parcel1 {    public class Contents{        private int value = 0;        public int getValue(){            return value;        }    }}

 

這是一個很簡單的內部類定義方式,你可以直接把一個類至於另一個類的內部,這種定義Contents類的方式被稱為內部類

那麼,就像程式碼10.1-1所展示的,程式設計師該如何訪問Contents中的內容呢?

如程式碼10.1-2 所示

 

public class Parcel1 {    public class Contents{        private int value = 0;        public int getValue(){            return value;        }    }    public Contents contents(){        return new Contents();    }    public static void main(String[] args) {        Parcel1 p1 = new Parcel1();
Parcel1.Contents pc1 = p1.contents(); System.out.println(pc1.getValue()); }}

 

輸出結果: 0

就像上面程式碼看到的那樣,你可以寫一個方法來訪問Contents,相當於指向了一個對Contents的引用,可以用外部類.內部類這種定義方式來建立一個對於內部類的引用,就像Parcel1.Contents pc1 = p1.contents();所展示的,而pc1 相當於持有了對於內部類Contents的訪問許可權。

現在,我就有一個疑問,如果10.1-2 中的contents方法變為靜態方法,pc1還能訪問到嗎?

 

編譯就過不去,那麼為什麼會訪問不到呢?請看接下來的分析。

10.2 連結到外部類的方式

看到這裡,你還不明白為什麼要採用這種方式來編寫程式碼,好像只是為了裝逼?或者你覺得重新定義一個類很麻煩,乾脆直接定義一個內部類得了,好像到現在並沒有看到這種定義內部類的方式為我們帶來的好處。請看下面這個例子10.2-1

 

public class Parcel2 {    private static int i = 11;    public class Parcel2Inner {        public Parcel2Inner(){            i++;        }        public int getValue(){            return i;        }    }    public Parcel2Inner parcel2Inner(){        return new Parcel2Inner();    }    public static void main(String[] args) {        Parcel2 p2 = new Parcel2();        for(int i = 0;i < 5;i++){            p2.parcel2Inner();        }        System.out.println("p2.i = " + p2.i);    }}

 

輸出結果: 16

當你建立了一個內部類物件的時候,此物件就與它的外圍物件產生了某種聯絡,如上面程式碼所示,內部類Parcel2Inner 是可以訪問到Parcel2中的i的值的,也可以對這個值進行修改。

那麼,問題來了,如何建立一個內部類的物件呢?程式設計師不能每次都寫一個方法返回外部類的物件吧?見程式碼10.2-2

 

public class Parcel3 {    public class Contents {        public Parcel3 dotThis(){            return Parcel3.this;        }        public String toString(){            return "Contents";        }    }    public Parcel3 contents(){        return new Contents().dotThis();    }    public String toString(){        return "Parcel3";    }    public static void main(String[] args) {        Parcel3 pc3 = new Parcel3();        Contents c = pc3.new Contents();        Parcel3 parcel3 = pc3.contents();        System.out.println(pc3);        System.out.println(c);        System.out.println(parcel3);    }}

 

輸出: Parcel3 Contents Parcel3

如上面程式碼所示,Parcel3內定義了一個內部類Contents,內部類中定義了一個方法dotThis(),這個方法的返回值為外部類的物件,在外部類中有一個contents()方法,這個方法返回的還是外部類的引用。

10.3 內部類與向上轉型

本文到現在所展示的都是本類持有內部類的訪問許可權,那麼,與此類無關的類是如何持有此類內部類的訪問許可權呢?而且內部類與向上轉型到底有什麼關係呢? 如圖10.3-1

public interface Animal {    void eat();}public class Parcel4 {    private class Dog implements Animal {        @Override        public void eat() {            System.out.println("啃骨頭");        }    }    public Animal getDog(){        return new Dog();    }    public static void main(String[] args) {        Parcel4 p4 = new Parcel4();        //Animal dog = p4.new Dog();        Animal dog = p4.getDog();        dog.eat();    }}

 

輸出: 啃骨頭

這個輸出大家肯定都知道了,Dog是由private修飾的,按說非本類的任何一個類都是訪問不到,那麼為什麼能夠訪問到呢? 仔細想一下便知,因為Parcel4 是public的,而Parcel4是可以訪問自己的內部類的,那麼Animal也可以訪問到Parcel4的內部類也就是Dog類,並且Dog類是實現了Animal介面,所以getDog()方法返回的也是Animal類的子類,從而達到了向上轉型的目的,讓程式碼更美妙。

10.4 定義在方法中和任意作用域內部的類

上面所展示的一些內部類的定義都是普通內部類的定義,如果我想在一個方法中或者某個作用域內定義一個內部類該如何編寫呢? 你可能會考慮這幾種定義的思路:

1.我想定義一個內部類,它實現了某個介面,我定義內部類是為了返回介面的引用

2.我想解決某個問題,並且這個類又不希望它是公共可用的,顧名思義就是封裝起來,不讓別人用

3.因為懶...

以下是幾種定義內部類的方式:

•一個在方法中定義的類(區域性內部類)•一個定義在作用域內的類,這個作用域在方法的內部(成員內部類)•一個實現了介面的匿名類(匿名內部類)•一個匿名類,它擴充套件了非預設構造器的類•一個匿名類,執行欄位初始化操作•一個匿名類,它通過例項初始化實現構造•定義在方法內部的類又被稱為區域性內部類

public class Parcel5 {        private Destination destination(String s){            class PDestination implements Destination{                String label;                public PDestination(String whereTo){                    label = whereTo;                }                @Override                public String readLabel() {                    return label;                }            }            return new PDestination(s);        }        public static void main(String[] args) {            Parcel5 p5 = new Parcel5();            Destination destination = p5.destination("China");            System.out.println(destination.readLabel());        }}

輸出 : China

如上面程式碼所示,你可以在編寫一個方法的時候,在方法中插入一個類的定義,而內部類中的屬性是歸類所有的,我在寫這段程式碼的時候很好奇,內部類的執行過程是怎樣的,Debugger走了一下發現當執行到p5.destination("China")的時候,先會執行return new PDestination(s),然後才會走PDestination的初始化操作,這與我們對其外部類的初始化方式是一樣的,只不過這個方法提供了一個訪問內部類的入口而已。 注: 區域性內部類的定義不能有訪問修飾符

•一個定義在作用域內的類,這個作用域在方法的內部

public class Parcel6 {        // 吃椰子的方法        private void eatCoconut(boolean flag){            // 如果可以吃椰子的話            if(flag){                class Coconut {                    private String pipe;                    public Coconut(String pipe){                        this.pipe = pipe;                    }                    // 喝椰子汁的方法                    String drinkCoconutJuice(){                        System.out.println("喝椰子汁");                        return pipe;                    }                }                // 提供一個吸管,可以喝椰子汁                Coconut coconut = new Coconut("用吸管喝");                coconut.drinkCoconutJuice();            }            /**             * 如果可以吃椰子的話,你才可以用吸管喝椰子汁             * 如果不能接到喝椰子汁的指令的話,那麼你就不能喝椰子汁             */            // Coconut coconut = new Coconut("用吸管喝");            // coconut.drinkCoconutJuice();        }        public static void main(String[] args) {            Parcel6 p6 = new Parcel6();            p6.eatCoconut(true);        }}

輸出: 喝椰子汁

如上面程式碼所示,只有程式設計師告訴程式,現在我想吃一個椰子,當程式接收到這條命令的時候,它回答好的,馬上為您準備一個椰子,並提供一個吸管讓您可以喝到新鮮的椰子汁。程式設計師如果不想吃椰子的話,那麼程式就不會為你準備椰子,更別說讓你喝椰子汁了。

•一個實現了匿名介面的類

我們都知道介面是不能被例項化的,也就是說你不能return 一個介面的物件,你只能是返回這個介面子類的物件,但是如果像下面這樣定義,你會不會表示懷疑呢?

public interface Contents {    int getValue();}public class Parcel7 {    private Contents contents(){        return new Contents() {            private int value = 11;            @Override            public int getValue() {                return value;            }        };    }    public static void main(String[] args) {        Parcel7 p7 = new Parcel7();        System.out.println(p7.contents().getValue());    }}

輸出 : 11

為什麼能夠返回一個介面的定義?而且還有 {},這到底是什麼鬼? 這其實是一種匿名內部類的寫法,其實和上面所講的內部類和向上轉型是相似的。也就是說匿名內部類返回的new Contents()其實也是屬於Contents的一個實現類,只不過這個實現類的名字被隱藏掉了,能用如下的程式碼示例來進行轉換:

public class Parcel7b {    private class MyContents implements Contents {        private int value = 11;        @Override        public int getValue() {            return 11;        }    }    public Contents contents(){        return new MyContents();    }    public static void main(String[] args) {        Parcel7b parcel7b = new Parcel7b();        System.out.println(parcel7b.contents().getValue());    }}

輸出的結果你應該知道了吧~! 你是不是覺得這段程式碼和 10.3 章節所表示的程式碼很一致呢?

•一個匿名類,它擴充套件了非預設構造器的類

如果你想返回一個帶有引數的構造器(非預設的構造器),該怎麼表示呢?

public class WithArgsConstructor {    private int sum;    public WithArgsConstructor(int sum){        this.sum = sum;    }    public int sumAll(){        return sum;    }}public class Parcel8 {    private WithArgsConstructor withArgsConstructor(int x){        // 返回WithArgsConstructor帶引數的構造器,執行欄位初始化        return new WithArgsConstructor(x){            // 重寫sumAll方法,實現子類的執行邏輯            @Override            public int sumAll(){                return super.sumAll() * 2;            }        };    }    public static void main(String[] args) {        Parcel8 p8 = new Parcel8();        System.out.println(p8.withArgsConstructor(10).sumAll());    }}

以上WithArgsConstructor 中的程式碼很簡單,定義一個sum的欄位,構造器進行初始化,sumAll方法返回sum的值,Parcel8中的withArgsConstructor方法直接返回x的值,但是在這個時候,你想在返回值上做一些特殊的處理,比如你想定義一個類,重寫sumAll方法,來實現子類的業務邏輯。 Java程式設計思想198頁中說 程式碼中的“;”並不是表示內部類結束,而是表示式的結束,只不過這個表示式正巧包含了匿名內部類而已。

•一個匿名類,它能夠執行欄位初始化

上面程式碼確實可以進行初始化操作,不過是通過構造器執行欄位的初始化,如果沒有帶引數的構造器,還能執行初始化操作嗎? 這樣也是可以的。

public class Parcel9 {    private Destination destination(String dest){        return new Destination() {            // 初始化賦值操作            private String label = dest;            @Override            public String readLabel() {                return label;            }        };    }    public static void main(String[] args) {        Parcel9 p9 = new Parcel9();        System.out.println(p9.destination("pen").readLabel());    }}

如果給欄位進行初始化操作,那麼形參必須是final的,如果不是final,編譯器會報錯,這部分提出來質疑,因為我不定義為final,編譯器也沒有報錯。 我考慮過是不是private的問題,當我把private 改為public,也沒有任何問題。

我不清楚是中文版作者翻譯有問題,還是經過這麼多Java版本的升級排除了這個問題,我沒有考證原版是怎樣寫的,這裡還希望有知道的大牛幫忙解釋一下這個問題。

•一個匿名類,它通過例項初始化實現構造

public abstract class Base {    public Base(int i){        System.out.println("Base Constructor = " + i);    }    abstract void f();}public class AnonymousConstructor {    private static Base getBase(int i){        return new Base(i){            {                System.out.println("Base Initialization" + i);            }            @Override            public void f(){                System.out.println("AnonymousConstructor.f()方法被呼叫了");            }        };    }    public static void main(String[] args) {        Base base = getBase(57);        base.f();    }}

輸出: Base Constructor = 57 Base Initialization 57 AnonymousConstructor.f()方法被呼叫了

這段程式碼和 "一個匿名類,它擴充套件了非預設構造器的類" 中屬於相同的範疇,都是通過構造器實現初始化的過程。

10.5 巢狀類

10.4 我們介紹了6種內部類定義的方式,現在我們來解決一下10.1 提出的疑問,為什麼contents()方法變成靜態的,會編譯出錯的原因:

如果不需要內部類與其外圍類之前產生關係的話,就把內部類宣告為static。這通常稱為巢狀類,也就是說巢狀類的內部類與其外圍類之前不會產生某種聯絡,也就是說內部類雖然定義在外圍類中,但是確實可以獨立存在的。巢狀類也被稱為靜態內部類。 靜態內部類意味著: (1)要建立巢狀類的物件,並不需要其外圍類的物件 (2)不能從巢狀類的物件中訪問非靜態的外圍類物件

程式碼示例 10.5-1

public class Parcel10 {    private int value = 11;    static int bValue = 12;    // 靜態內部類    private static class PContents implements Contents {        // 編譯報錯,靜態內部類PContents中沒有叫value的欄位        @Override        public int getValue() {            return value;        }        // 編譯不報錯,靜態內部類PContents可以訪問靜態屬性bValue        public int f(){            return bValue;        }    }    // 普通內部類    private class PDestination implements Destination {        @Override        public String readLabel() {            return "label";        }    }    // 編譯不報錯,因為靜態方法可以訪問靜態內部類    public static Contents contents(){        return new PContents();    }    // 編譯報錯,因為非靜態方法不能訪問靜態內部類    public Contents contents2(){        Parcel10 p10 = new Parcel10();        return p10.new PContents();    }    // 編譯不報錯,靜態方法可以訪問非靜態內部類    public static Destination destination(){        Parcel10 p10 = new Parcel10();        return p10.new PDestination();    }    // 編譯不報錯,非靜態方法可以訪問非靜態內部類    public Destination destination2(){        return new PDestination();    }}

由上面程式碼可以解釋,10.1編譯出錯的原因是 靜態方法不能直接訪問非靜態內部類,而需要通過建立外圍類的物件來訪問普通內部類。

介面內部的類

納尼?介面內部只能定義方法,難道介面內部還能放一個類嗎?可以! 正常情況下,不能在介面內部放置任何程式碼,但是巢狀類作為介面的一部分,你放在介面中的任何類預設都是public和static的。因為類是static的,只是將巢狀類置於介面的名稱空間內,這並不違反介面的規則,你甚至可以在內部類實現外部類的介面,不過一般我們不提倡這麼寫

 

public interface InnerInterface {    void f();    class InnerClass implements InnerInterface {        @Override        public void f() {            System.out.println("實現了介面的方法");        }        public static void main(String[] args) {            new InnerClass().f();        }    }    // 不能在介面中使用main方法,你必須把它定義在介面的內部類中//    public static void main(String[] args) {}}

 

輸出: 實現了介面的方法

內部類實現多重繼承

在Java中,類與類之間的關係通常是一對一的,也就是單項繼承原則,那麼在介面中,類與介面之間的關係是一對多的,也就是說一個類可以實現多個介面,而介面和內部類結合可以實現"多重繼承",並不是說用extends關鍵字來實現,而是介面和內部類的對多重繼承的模擬實現。

參考chenssy的文章 http://www.cnblogs.com/chenssy/p/3389027.html 已經寫的很不錯了。

 

public class Food {    private class InnerFruit implements Fruit{        void meakFruit(){            System.out.println("種一個水果");        }    }    private class InnerMeat implements Meat{        void makeMeat(){            System.out.println("煮一塊肉");        }    }    public Fruit fruit(){        return new InnerFruit();    }    public Meat meat(){        return new InnerMeat();    }    public static void main(String[] args) {        Food food = new Food();        InnerFruit innerFruit = (InnerFruit)food.fruit();        innerFruit.meakFruit();        InnerMeat innerMeat = (InnerMeat) food.meat();        innerMeat.makeMeat();    }}

輸出: 種一個水果 煮一塊肉

10.6 內部類的繼承

內部類之間也可以實現繼承,與普通類之間的繼承相似,不過不完全一樣。

public class BaseClass {    class BaseInnerClass {        public void f(){            System.out.println("BaseInnerClass.f()");        }    }    private void g(){        System.out.println("BaseClass.g()");    }}/** *  可以看到,InheritInner只是繼承自內部類BaseInnerClass,而不是外圍類 *  但是預設的構造方式會報編譯錯誤, *  必須使用類似enclosingClassReference.super()才能編譯通過 *  用來來說明內部類與外部類物件引用之間的關聯。 * */public class InheritInner extends BaseClass.BaseInnerClass{    // 編譯出錯//    public InheritInner(){}    public InheritInner(BaseClass bc){        bc.super();    }    @Override    public void f() {        System.out.println("InheritInner.f()");    }    /*    * 加上@Override 會報錯,因為BaseInnerClass 中沒有g()方法    * 這也是為什麼覆寫一定要加上Override註解的原因,否則預設是本類    * 中持有的方法,會造成誤解,程式設計師以為g()方法是重寫過後的。    @Override    public void g(){        System.out.println("InheritInner.g()");    }*/    public static void main(String[] args) {        BaseClass baseClass = new BaseClass();        InheritInner inheritInner = new InheritInner(baseClass);        inheritInner.f();    }}

輸出:InheritInner.f()

10.7 內部類的覆蓋

關於內部類的覆蓋先來看一段程式碼:

public class Man {    private ManWithKnowledge man;    protected class ManWithKnowledge {        public void haveKnowledge(){            System.out.println("當今社會是需要知識的");        }    }    // 我們想讓它輸出子類的haveKnowledge()方法    public Man(){        System.out.println("當我們有了一個孩子,我們更希望他可以當一個科學家,而不是網紅");        new ManWithKnowledge().haveKnowledge();    }}// 網紅public class InternetCelebrity extends Man {    protected class ManWithKnowledge {        public void haveKnowledge(){            System.out.println("網紅是當今社會的一種病態");        }    }    public static void main(String[] args) {        new InternetCelebrity();    }}

輸出:當我們有了一個孩子,我們更希望他可以當一個科學家,而不是網紅 當今社會是需要知識的

我們預設內部類是可以覆蓋的。所以我們想讓他輸出 InternetCelebrity.haveKnowledge() ,來實現我們的猜想,但是卻輸出了ManWithKnowledge.haveKnowledge()方法。 這個例子說明當繼承了某個外圍類的時候,內部類並沒有發生特別神奇的變化,兩個內部類各自獨立,都在各自的名稱空間內。

10.8 關於原始碼中內部類的表示

由於每個類都會產生一個.class 檔案,包含了建立該型別物件的全部資訊 同樣的,內部類也會生成一個.class 檔案 表示方法為: OneClass$OneInnerClass

後記: 內部類屬於Java語言的高階特性,內部類在實際的應用場景比較少,內部類可以讓程式碼變的更加優雅,但是對於平常開發的話用處不是很大,畢竟不是所有同事都能瞭解全面內部類的特性和用法,所以在平常開發中儘量避免使用內部類,加大維護成本。內部類應該在設計階段考慮使用,你應該區分內部類和介面的應用場景,就算用不到,你也get到了一項新技能,就算裝逼也能落落大方的不是嗎?

10.9 內部類的優點

1、封裝部分程式碼,當你建立一個內部類的時候,該內部類預設持有外部類的引用;

2、內部類具有一定的靈活性,無論外圍類是否繼承某個介面的實現,對於內部類都沒有影響;

3、內部類能夠有效的解決多重繼承的問題。

 


 

Java 極客技術公眾號,是由一群熱愛 Java 開發的技術人組建成立,專注分享原創、高質量的 Java 文章。如果您覺得我們的文章還不錯,請幫忙讚賞、在看、轉發支援,鼓勵我們分享出更好的文章。

關注公眾號,大家可以在公眾號後臺回覆“部落格園”,免費獲得作者 Java 知識體系/面試必看資料。

相關推薦

Java部類操作

  10.1 如何定義內部類 如程式碼10.1-1 所示 public class Parcel1 { public class Contents{ private int value = 0;​ public int getValue(){

Java 部類特性總結(吐血之作)

內部 不能 今天 了解 基本 靜態 外部類 pro this PS:今天花了整個下午時間看內部類相關的內容,因知識點多而雜,故記之如下。 一、內部類的作用 內部類看起來是一種代碼隱藏機制:將類置於其他類的內部。它還了解外部類,並能與之通信;使用內部類可以實現閉包;內部

java部類使用小結

內部類的宣告與訪問 內部類可以是static的也可以用其它四種訪問修飾符(而外部類只能使用public和 default修飾)。內部類所能實現的功能外部類也同樣可以全部實現,只是使用內部類可以使其更加簡潔高效。 內部類是一個編譯時概念,一旦編譯成功就會變成兩個完全不同

Java部類的定義及使用

一、定義 1.在一個類的內部進行其他類結構的巢狀的操作。 例: class Outer{ private String msg = "Hello World!"; //定義一個內部類 //*********************************

JAVA部類的繼承和覆蓋問題

在JAVA中,由於內部類的構建器必須連線到指向其外圍類物件的引用,所以在繼承內部類的時候會變得很複雜。問題在於指向外圍類物件的祕密引用必須得到初始化,而在匯出類中不再存在可連線的預設物件,我們必須使用

java部類的訪問呼叫

從Java1.1開始引入了內部類以來,它就引起了人們的激烈爭論。其實任何優秀的語言特性用得不好就是濫用,內部類用得不好就會導致程式碼像迷宮一樣,導致出現毫無重用的綜合徵。1、內部類分為成員內部類、靜態巢狀類、方法內部類、匿名內部類。幾種內部類的共性:A、內部類仍然是一個獨立

解決JAVA部類所對應的外部類引用初始化的問題

java內部類的分類 java內部類的分類:成員內部類、區域性內部類、靜態內部類(巢狀類)、匿名內部類。 在構建內部類物件時,需要一個指向其外部類物件的引用,而且這種引用的傳遞是通過內部類的構造器來完成的。 如果編譯器訪問不到這個引用就會報錯。 CASE 1: // 用.n

JAVA部類和匿名部類的區別,分別在什麼時候使用它們?

今天沒事,抽出時間總結了一下很多開發人員都想弄明白的一些JAVA基礎知識(內部類和匿名內部類)。 一、JAVA中內部類和匿名內部類的區別          內部類:內部類可以是static的或者非static的,static內部類只能包含靜態方法和靜態類變數,只能訪問外部類的

Java 部類、靜態部類、列舉類

一、內部類 在另一個類中定義的類 內部類作用 1、內部類提供了更好的封裝。只能讓外部類直接訪問,不允許同一個包中的其他類直接訪問。 2、內部類可以直接訪問外部類的私有屬性,內部類被當成其外部類成員。當外部類不能訪問內部類的內部屬性。 內

java部類的建立四種情況,三種方式,及內部資料訪問許可權

內部類和外部類的關係,及內部靜態類的資料訪問許可權,宣告方式。 第一種,在外部類內部宣告使用內部類,內部類的型別為static和非 static型別,內部類資料型別為private,protected,public 型別的訪問許可權。外部類為非靜態宣告和許可權如下: p

java部類訪問區域性變數為什麼要定義區域性變數為final

因為方法內定義的變數是區域性變數,離開該方法,變數就失去了作用,也就會自動被消除,而內部類卻不會離開它所在方法就失去作用,它有更廣的生命週期,下面通過一個例項加以說明: 如例中所示,在外部類Outer中聲明瞭一個內部類TimerPrint,這個類中的方法引用了方法start

Java部類的記憶體洩露問題

package com.example.temptemp; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.Text

java部類在區域性時,訪問許可權》

/* 內部類定義在區域性時, 1,不可以被成員修飾符修飾 2,可以直接訪問外部類中的成員,因為還持有外部類中的引用。 但是不可以訪問它所在的區域性中的變數。只能訪問被final修飾的區域性變數。 *

Java部類和異常處理

1、 內部類 內部類的訪問規則: 1) 內部類可以訪問外部類的成員包括私有。 之所以可以直接訪問外部類的成員,是因為內部類持有一個外部類的引用 , 格式: 外部類名.this 2) 外部類要訪問內部類,必須建立內部類物件。 當內部類處於外

關於Java部類的一些概念整理

    把一個類放到另一個類的內部定義,這個定義在其他類內部的類就被稱為內部類。     內部類的作用:     (1).內部類提供了更好的封裝,可以把內部類隱藏在外部類之內,不允許同一個包中的其他類訪問該類。     (2).內部類成員可以直接訪問外部類的私有資料,因為內

java部類和異常類

這是在eclipse中建立的一個Example8_2的類,其中有些錯誤,我想在這裡註明一下。只是想以後自己看看,希望不要在出現這樣的錯誤。 package s8_2; /**  * @author Administrator  *本節主要是講內部類和異常類  */ /

Java部類和靜態部類的區別

內部類和靜態內部類 示例 public class OuterClass { private int numPrivate = 1; public int numPublic = 2; public static int numPublicStatic = 3; private

Java匿名部類使用外部類方法的形參或區域性變數必須宣告為final

 對於這個問題,首先我們應該明確的一點是對於匿名內部類,它可能引用三種外部變數:外部類的成員變數外部方法或作用域內的區域性變數外部方法的引數而第一種變數是不需要宣告為final的,但後兩種是需要宣告為final的。那這是為什麼呢?不急,我們首先來看第一個知識點。知識點一,匿名內部類同所有類一

java/c++部類、匿名類

1.java中的內部類: class Outside{ private String nameString ; private int age; Outside() {

Java匿名部類this的小知識(待補充完整)

今日在看到Enumeration 藉口的原始碼時發現,Enumeration 介面的asIterator 方法返回了一個迭代器,並使用匿名內部類(實現介面的匿名內部類)。對迭代器中的方法進行了實現 default Iterator<E> a