java 反射實例化內部類


內部類的初始化同一般類的初始化基本相同,只是內部類的類名全稱有些區別。下面定義了一個Outer類和一個Inner類:

Java代碼   收藏代碼
  1. public class Outer{  
  2.    public class Inner{  
  3.    }  
  4. }  


   通過如下方法可以得到Inner類的類名:

Java代碼   收藏代碼
  1. public class Outer{  
  2.    public class Inner{  
  3.    }  
  4.    public static void main(String[] args){  
  5.       System.out.println(Inner.class);  
  6.    }  
  7. }  


   從輸出結果可以看到,Inner的類名是xxx.xxx.Outer$Inner這種形式的。這是Java中所謂的synthetic name。也就是這個名字在源代碼中是找不到對應的文件的,是編譯器經過修飾之后的名字。
   反射實例化內部類的代碼如下:

Java代碼   收藏代碼
  1. public class Outer{  
  2.    public class Inner{  
  3.    }  
  4.    public static void main(String[] args){  
  5.       System.out.println(Inner.class);  
  6.       //查看class是否有構造函數  
  7.       System.out.println(Inner.class.getConstructors().length);  
  8.       //獲取第一個構造函數  
  9.       System.out.println(Inner.class.getConstructors()[0]);  
  10.       //用構造函數初始化內部類  
  11.       System.out.println(Inner.class.getConstructors()[0].newInstance(new Outer());  
  12.    }  
  13. }  


    從上面代碼的打印輸出可以看到,公開非靜態內部類的默認構造函數需要一個外圍類的實例。
    如果是public static的內部類,則默認構造函數是一個無參的構造函數。如果把Inner類的public關鍵字去掉,運行上面代碼會發現拋錯了,因為找不到 Inner的構造函數。這個時候只需要將getConstructors方法換成getDeclaredConstructors就可以了。
    如果內部類是私有的,在初始化的時候要將構造函數的訪問設置成true。如下:

Java代碼   收藏代碼
  1. public class Outer{  
  2.    private class Inner{  
  3.    }  
  4.    public static void main(String[] args){  
  5.       System.out.println(Inner.class);  
  6.       //查看class是否有構造函數  
  7.       System.out.println(Inner.class.getDeclaredConstructors().length);  
  8.       //獲取第一個構造函數  
  9.       Constructor c = Inner.class.getDeclaredConstructors()[0];  
  10.       //將c設置成可訪問        
  11.       c.setAccessible(true);  
  12.       //用構造函數初始化內部類  
  13.       System.out.println(c.newInstance(new Outer());  
  14.    }  
  15. }  


    當然,構造類的時候還是要遵循Java的可見性的,比如在其他類里面就沒有辦法初始化一個類中的私有內部類。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM