反射無視私有

1.私有構造函數的調用:
主要的類:java.lang.reflect.Constructor

首先要拿到構造方法,具體如下:
Class clazz = Class.forName("Bean"); 
Constructor[]  cons = clazz.getDeclaredConstructors();
這樣拿到的cons數組保存着所有的這個類的構造函數,包括私有的和公有的。
迭代並調用con.toGenericString()可以拿到每個構造方法的全限定名(帶修飾符,帶參數)。
如果要拿單個構造方法,可以調用getDeclaredConstructor(Class args);來拿,只要參數匹配了就可以得到,如果沒有參數,則傳null即可。  

然後需要調用Constructor的方法setAccessible設置爲true,表示允許使用私有構造函數。這個方法是父類AccessibleObject的方法,這個類的自類有Constructor, Field, Method分別代表構造函數,成員變量,和成員方法。也就是說使用這個方法,可以訪問類的所有的方法、變量、構造函數。  

最後,使用Constructor的newInstance方法就可以把對象創建出來了:
Bean bean = (Bean)con.newInstance(Object args);
沒有參數的構造函數可以傳null進去。 

2.調用私有的方法:
主要的類:java.lang.reflect.Method

首先還是要拿到那個私有的方法,可以調用
Method[] ms =  clazz.getDeclaredMethods();來拿到所有的方法的集合。
也可以拿某個單獨的方法:getDeclaredMethod(String name, Class... parameterTypes)匹配名字和參數的方法會被拿到,方法若沒有參數傳null.
同樣可以調用toGenericString()看全限定名。

然後同樣需要調用setAccessible(true)來設置可以方法私有方法。

最後,就可以使用method.invoke(bean, Object args);來調用這個方法。兩個參數分別是對象,和這個方法的參數。

3.調用私有成員變量,也叫字段。
主要類:java.lang.reflect.Field

首先還是要拿到要使用的字段:
還是兩種,拿全部:Field[] fs =  clazz.getDeclaredFields();
拿某個:clazz.getDeclaredField(String fieldName);

老步驟:setAccessible(true)

最後, f.get(obj) ,就能拿到傳入對象的私有變量。

測試:

Java代碼 複製代碼
  1. MyBean.java :    
  2.   
  3. package cn.yzj.entities;    
  4.   
  5. public class MyBean   
  6. {   
  7.  private String name;   
  8.  private Integer age;   
  9.     
  10.  private MyBean()   
  11.  {   
  12.   this.name ="ABC";   
  13.  }    
  14.   
  15.  private MyBean(String name,Integer age)   
  16.  {   
  17.   this.name = name;   
  18.   this.age = age;   
  19.  }   
  20.     
  21.  public String getName()   
  22.  {   
  23.   return name;   
  24.  }   
  25.  public void setName(String name)   
  26.  {   
  27.   this.name = name;   
  28.  }   
  29.     
  30.  private void printName()   
  31.  {   
  32.   System.out.println(this.name);   
  33.  }   
  34. }   
MyBean.java : 

package cn.yzj.entities; 

public class MyBean
{
 private String name;
 private Integer age;
 
 private MyBean()
 {
  this.name ="ABC";
 } 

 private MyBean(String name,Integer age)
 {
  this.name = name;
  this.age = age;
 }
 
 public String getName()
 {
  return name;
 }
 public void setName(String name)
 {
  this.name = name;
 }
 
 private void printName()
 {
  System.out.println(this.name);
 }
} 



Test1.java:

Java代碼 複製代碼
  1. package cn.yzj;    
  2.   
  3. import java.lang.reflect.Constructor;   
  4. import java.lang.reflect.Field;   
  5. import java.lang.reflect.InvocationTargetException;   
  6. import java.lang.reflect.Method;    
  7.   
  8. import cn.yzj.entities.MyBean;    
  9.   
  10. public class Test1   
  11. {   
  12.  public static void main(String[] args) throws ClassNotFoundException,   
  13.    IllegalArgumentException, InstantiationException,   
  14.    IllegalAccessException, InvocationTargetException,   
  15.    SecurityException, NoSuchMethodException   
  16.  {   
  17.   Class clazz = Class.forName("cn.yzj.entities.MyBean");    
  18.   
  19.   // 獲得私有成員變量並返回.   
  20.   // getField(clazz);    
  21.   
  22.   // 調用私有方法   
  23.   // getMethod(clazz);    
  24.   
  25.   // 用私有構造方法構造對象並返回.   
  26.   // getConstrutor(clazz);    
  27.   
  28.  }    
  29.   
  30.   
  31.  //用私有構造方法構建實例的方法   
  32.  private static MyBean getConstrutor(Class clazz)   
  33.    throws NoSuchMethodException, InstantiationException,   
  34.    IllegalAccessException, InvocationTargetException   
  35.  {    
  36.   
  37.   // 拿所有的構造方法.   
  38.   /*  
  39.    * Constructor[] cons = clazz.getDeclaredConstructors(); for(Constructor  
  40.    * con : cons) { System.out.println(con.toGenericString()); }  
  41.    */    
  42.   
  43.   // 1.拿無參數的構造方法.   
  44.   Constructor con = clazz.getDeclaredConstructor(null);    
  45.   
  46.   // 2.設置可以訪問.   
  47.   con.setAccessible(true);    
  48.   
  49.   // 3.創建實例   
  50.   MyBean myBean = (MyBean) con.newInstance(null);   
  51.   return myBean;   
  52.  }    
  53.   
  54.  private static Object getField(Class clazz) throws NoSuchMethodException,   
  55.    InstantiationException, IllegalAccessException,   
  56.    InvocationTargetException   
  57.  {   
  58.   MyBean myBean = getConstrutor(clazz);    
  59.   
  60.   Field[] fs = clazz.getDeclaredFields();    
  61.   
  62.   for (Field f : fs)   
  63.   {   
  64.    System.out.println(f.toGenericString());   
  65.   }    
  66.   
  67.   fs[0].setAccessible(true);    
  68.   
  69.   return fs[0].get(myBean);   
  70.  }    
  71.   
  72.  private static void getMethod(Class clazz) throws NoSuchMethodException,   
  73.    InstantiationException, IllegalAccessException,   
  74.    InvocationTargetException   
  75.  {   
  76.   MyBean myBean = getConstrutor(clazz);    
  77.   
  78.   Method[] ms = clazz.getDeclaredMethods();    
  79.   
  80.   for (Method m : ms)   
  81.   {   
  82.    System.out.println(m.toGenericString());   
  83.   }    
  84.   
  85.   ms[0].setAccessible(true);    
  86.   
  87.   ms[0].invoke(myBean, null);   
  88.  }    
  89.   
  90. }  
package cn.yzj; 

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; 

import cn.yzj.entities.MyBean; 

public class Test1
{
 public static void main(String[] args) throws ClassNotFoundException,
   IllegalArgumentException, InstantiationException,
   IllegalAccessException, InvocationTargetException,
   SecurityException, NoSuchMethodException
 {
  Class clazz = Class.forName("cn.yzj.entities.MyBean"); 

  // 獲得私有成員變量並返回.
  // getField(clazz); 

  // 調用私有方法
  // getMethod(clazz); 

  // 用私有構造方法構造對象並返回.
  // getConstrutor(clazz); 

 } 


 //用私有構造方法構建實例的方法
 private static MyBean getConstrutor(Class clazz)
   throws NoSuchMethodException, InstantiationException,
   IllegalAccessException, InvocationTargetException
 { 

  // 拿所有的構造方法.
  /*
   * Constructor[] cons = clazz.getDeclaredConstructors(); for(Constructor
   * con : cons) { System.out.println(con.toGenericString()); }
   */ 

  // 1.拿無參數的構造方法.
  Constructor con = clazz.getDeclaredConstructor(null); 

  // 2.設置可以訪問.
  con.setAccessible(true); 

  // 3.創建實例
  MyBean myBean = (MyBean) con.newInstance(null);
  return myBean;
 } 

 private static Object getField(Class clazz) throws NoSuchMethodException,
   InstantiationException, IllegalAccessException,
   InvocationTargetException
 {
  MyBean myBean = getConstrutor(clazz); 

  Field[] fs = clazz.getDeclaredFields(); 

  for (Field f : fs)
  {
   System.out.println(f.toGenericString());
  } 

  fs[0].setAccessible(true); 

  return fs[0].get(myBean);
 } 

 private static void getMethod(Class clazz) throws NoSuchMethodException,
   InstantiationException, IllegalAccessException,
   InvocationTargetException
 {
  MyBean myBean = getConstrutor(clazz); 

  Method[] ms = clazz.getDeclaredMethods(); 

  for (Method m : ms)
  {
   System.out.println(m.toGenericString());
  } 

  ms[0].setAccessible(true); 

  ms[0].invoke(myBean, null);
 } 

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章