反射私有方法

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.   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值