Java 一個類中能夠嵌套另一個類,語法格式以下:html
class OuterClass { // 外部類 // ... class NestedClass { // 嵌套類,或稱爲內部類 // ... } }
嵌套類有以下幾種類型:java
最簡單的一種內部類,形式以下,跟其餘變量同樣,是一個類中的一個成員jvm
class Outer { String str = "hello"; public Outer(String str) { this.str = str; } /* 內部類 */ class Inner { public void showStr() { System.out.println(str); } } }
編譯器會在編譯時生成外部類和內部類兩個字節碼文件,還會給內部類的無參構造函數增長一個參數,爲外部類的一個應用,且指向了外部類,故能夠隨意使用外部類一切。函數
側面說明成員內部類依賴於外部類的優先建立,否則會初始化失敗this
定義在一個方法或者一個做用域裏面的類,局部內部類的訪問僅限於方法內或者該做用域內spa
class MyClass{ public MyClass() { } } class Outer{ public Outer(){ } public MyClass getInner{ /* 局部內部類 */ class Inner extends MyClass{ int age = 0; } return new Inner(); } }
局部內部類就像是方法裏面的一個局部變量同樣,是不能有 public、protected、private 以及 static 修飾符的線程
先看一下官方給的例子code
public class HelloWorldAnonymousClasses { /** * 包含兩個方法的HelloWorld接口 */ interface HelloWorld { public void greet(); public void greetSomeone(String someone); } public void sayHello() { // 一、局部類EnglishGreeting實現了HelloWorld接口 class EnglishGreeting implements HelloWorld { String name = "world"; public void greet() { greetSomeone("world"); } public void greetSomeone(String someone) { name = someone; System.out.println("Hello " + name); } } HelloWorld englishGreeting = new EnglishGreeting(); // 二、匿名類實現HelloWorld接口 HelloWorld frenchGreeting = new HelloWorld() { String name = "tout le monde"; public void greet() { greetSomeone("tout le monde"); } public void greetSomeone(String someone) { name = someone; System.out.println("Salut " + name); } }; // 三、匿名類實現HelloWorld接口 HelloWorld spanishGreeting = new HelloWorld() { String name = "mundo"; public void greet() { greetSomeone("mundo"); } public void greetSomeone(String someone) { name = someone; System.out.println("Hola, " + name); } }; englishGreeting.greet(); frenchGreeting.greetSomeone("Fred"); spanishGreeting.greet(); } public static void main(String... args) { HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses(); myApp.sayHello(); } }
匿名類表達式包含如下內部分:htm
本部分參考JAVA匿名內部類(Anonymous Classes)對象
靜態內部類是不須要依賴於外部類的,而且它不能使用外部類的非static成員變量或者方法,這個和普通靜態方法不能訪問非靜態方法或變量的原理同樣,具體能夠了解一下類的加載生命週期。
簡單地說就是靜態變量或方法是屬於類的,非靜態方法或變量是屬於對象的,jvm加載類的時候就爲類的靜態變量或方法分配內存的,而非靜態的須要等到要初始化對象時候纔給分配內存,而這個過程是動態的,也就是等到咱們何時想用,纔會有累的初始化過程。
簡單舉個例子:
class Outer { int a = 1 static int a = 2; public Outter() { } /* 靜態內部類 */ static class Inner { public Inner() { System.out.println(a); // 編譯會報錯 System.out.println(b); } } }
使用:
public class Test { public static void main(String[] args) { Outer.Inner inner = new Outer.Inner(); } }
爲何在 Java 中須要內部類?總結一下主要有如下四點內部類的使用場景和好處: