JAVA反射(Reflect)的使用

反射方法Method

getDeclaredMethod是获取该类声明的方法,不包括继承的。

Method getDeclaredMethod(String name, Class… parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 还有一个getMethod是只能获取public的方法 getMethod(String name, Class… parameterTypes)
返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 name参数是方法名;parameterTypes 参数是按声明顺序标识该方法形参类型的 Class 对象的一个数组
如:

LogFactory.class.getDeclaredMethod("functionName",new Class[]{String.class,int.class})

如果方法没有参数,提供null或者省略都可以。
method.invoke中,invoke(Object obj, Object… args) ,obj是对象,如果是静态方法,填入null;args参数是一个Object对象数组,如 new Object[] {“test”, new Integer(10)} 下面的例子是想要反射common logging 包里的LogFactory getContextClassLoader方法。这是一个private static方法

Method method = LogFactory.class.getDeclaredMethod("getContextClassLoader");
method.setAccessible(true); // 如果是private的方法,要把它设为可访问
ClassLoader classLoader = (ClassLoader)method.invoke(null);

反射属性Field

和method差不多,也有getDeclaredField和getField方法。
可以通过field.get来获取值,参数是你要获取的是哪个对象的属性。如果是静态变量,填入null
另外可以通过field.set来赋值。

Field field = LogFactory.class.getDeclaredField("factories");
field.setAccessible(true);
Hashtable obj = (Hashtable)field.get(null);

例子

在SesstionState里有一个ThreadLocal的pravate tss变量,我们要取到这个变量,并且调用它的remove方法。注意:ThreadLocal的对象是在每个线程都存有一个map,把值存在那里,所以,必须和原线程一致才能取到他的值。

// SessionState里有一个private static的tss局部变量
Class clazz = SessionState.class;
Field field = clazz.getDeclaredField("tss"); // 由于是private的,不能通过getField获取
field.setAccessible(true); // 设为可访问
ThreadLocal threadLocal = (ThreadLocal)field.get(sessionState);// 通过field.get(对象) 获取它的值
threadLocal.remove();
updatedupdated2023-12-062023-12-06