1.成員內部類:類(外部類)中直接定義的內部類
1.成員內部類
2.方法內部類:在一個方法中定義的內部類2.靜態成員內部類
3.匿名內部類:(我認爲這個也可以算一種方法內的類)
2.成員內部類
作爲外部類的一個成員存在,與外部類的屬性、方法並列。
1.成員內部類:
需要外部類對象才能實例化,可以通過 外部類名.this.外部類成員
成員內部類可以訪問外部類的靜態與非靜態成員,而自己只能聲明非靜態成員(對外啥都行,對內不行)
2.靜態成員內部類:class Testin { private String s ="這是外部類實例變量"; private static String s1="這是外部類靜態變量"; class B{ //private static String s1="papapa";報錯 private String s1="papapa"; public void go(){ System.out.println("這是內部類B的go方法"+s1); System.out.println("這是內部類B的go方法"+Testin.this.s); System.out.println("這是內部類B的go方法"+Testin.this.s1); } } } public class Test { public static void main(String[] args) { (new Testin()).new B().go();//需要外部對象創建內部對象 } } /* 這是內部類B的go方法papapa 這是內部類B的go方法這是外部類實例變量 這是內部類B的go方法這是外部類靜態變量 */
不需要需要外部類對象實例化,可以通過 外部類名.外部類成員
成員內部類可以訪問外部類的非靜態成員,而自己只能聲明靜態和非靜態成員(對外不行,對內啥都行)
class Testin { private String s ="這是外部類實例變量"; private static String s1="這是外部類靜態變量"; static class B{ private static String s="papapa"; private String s1="papapa"; public void go(){ System.out.println("這是內部類B的go方法"+s); System.out.println("這是內部類B的go方法"+s1); //System.out.println("這是內部類B的go方法"+Testin.this.s);報錯 System.out.println("這是內部類B的go方法"+Testin.s1); } } } public class 括號匹配 { public static void main(String[] args) { new Testin.B().go();//需要外部對象創建內部對象 } } /* 這是內部類B的go方法papapa 這是內部類B的go方法papapa 這是內部類B的go方法這是外部類靜態變量 */
作爲方法局部變量存在,不能被public, protected, private和static修飾,只能訪問方法中定義的final類型的局部變量(原因在最後)。
public class Test { private String s ="全局變量"; final String s1 ="全局final變量"; final int n=4; public void method(){ final String s2 ="局部final變量";//方法內的變量只有final變量才能被方法內部類訪問 String s3 = "局部變量"; class B{ public void show(){ System.out.println(s); System.out.println(s1); System.out.println(s2); //System.out.println(s3);報錯 } } new B().show(); } public static void main(String[] args) { new Test().method(); } } /* 全局變量 全局final變量 局部final變量 */
它也是在方法中使用,所以我喜歡把它也歸在局部內部類裏面...他是在我們new 對象時,new接口或者抽象類,然後直接在{}塊裏重寫抽象方法,這樣的類沒有名字且只使用這一次,23點了代碼就偷下懶就不貼了。我們創建線程時常用。
5.爲什麼局部內部類和匿名內部類需要用到的外部變量得用final修飾
因爲其實內部類和外部類編譯之後,實際上是生成了兩個.class文件, 一個out.class 一個out$inner.class,那內部類如何訪問外部類成員呢?其實內部類實際上保存了一個外部內的引用,可以反編譯內部類class文件看,當(局部內部類和匿名內部類)使用外部類成員變量或者方法局部變量時,會有方法內修改了外部類成員變量或者方法局部變量,而(局部內部類和匿名內部類)並不能獲取到修改情況,反之亦然,會導致外部與局部之間變量值的不匹配,所以乾脆簡單粗暴的要求必須是final的,誰都別想改。