內部類的初始化同一般類的初始化基本相同,只是內部類的類名全稱有些區別。下面定義了一個Outer類和一個Inner類:
- public class Outer{
- public class Inner{
- }
- }
通過如下方法可以得到Inner類的類名:
- public class Outer{
- public class Inner{
- }
- public static void main(String[] args){
- System.out.println(Inner.class);
- }
- }
從輸出結果可以看到,Inner的類名是xxx.xxx.Outer$Inner這種形式的。這是Java中所謂的synthetic name。也就是這個名字在源代碼中是找不到對應的文件的,是編譯器經過修飾之后的名字。
反射實例化內部類的代碼如下:
- public class Outer{
- public class Inner{
- }
- public static void main(String[] args){
- System.out.println(Inner.class);
- //查看class是否有構造函數
- System.out.println(Inner.class.getConstructors().length);
- //獲取第一個構造函數
- System.out.println(Inner.class.getConstructors()[0]);
- //用構造函數初始化內部類
- System.out.println(Inner.class.getConstructors()[0].newInstance(new Outer());
- }
- }
從上面代碼的打印輸出可以看到,公開非靜態內部類的默認構造函數需要一個外圍類的實例。
如果是public static的內部類,則默認構造函數是一個無參的構造函數。如果把Inner類的public關鍵字去掉,運行上面代碼會發現拋錯了,因為找不到 Inner的構造函數。這個時候只需要將getConstructors方法換成getDeclaredConstructors就可以了。
如果內部類是私有的,在初始化的時候要將構造函數的訪問設置成true。如下:
- public class Outer{
- private class Inner{
- }
- public static void main(String[] args){
- System.out.println(Inner.class);
- //查看class是否有構造函數
- System.out.println(Inner.class.getDeclaredConstructors().length);
- //獲取第一個構造函數
- Constructor c = Inner.class.getDeclaredConstructors()[0];
- //將c設置成可訪問
- c.setAccessible(true);
- //用構造函數初始化內部類
- System.out.println(c.newInstance(new Outer());
- }
- }
當然,構造類的時候還是要遵循Java的可見性的,比如在其他類里面就沒有辦法初始化一個類中的私有內部類。

