Java 反射机制[Method反射]

阅读更多

Java 反射机制[Method反射]

接着上一篇Java 反射机制[Field反射],通过调用Person类的setName方法将obj的name字段的Value设置为"callPersonSetNameMethod"来了解什么是Method反射示例代码很简单,很容易理解。

可以看到Method.invoke()实际上并不是自己实现的反射调用逻辑,而是委托给sun.reflect.MethodAccessor来处理。 真正的反射是调用MethodAccessor.invoke()真正完成反射调用。看源码可以发现MethodAccessor.invoke() 方法中出现了很多跟Cached有关的变量,说明method的反射十分消耗性能。

Java Code

/*
* System Abbrev :
* system Name :
* Component No :
* Component Name:
* File name :ReflectTestMain.java
* Author :Qiuzhenping
* Date :2014-10-25
* Description :
*/

/* Updation record 1:
* Updation date : 2014-10-25
* Updator : Qiuzhenping
* Trace No:
* Updation No:
* Updation Content:
*/
package com.qiuzhping.reflect.main;

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


/**
*
* 反射就是把Java类中的各种成分映射成相应的Java类。
*
*
* @author Qiuzhenping
* @version [Version NO, 2014-10-25]
* @see [Related classes/methods]
* @since [product/module version]
*/
public class ReflectTestMain {

/**
*/
public ReflectTestMain() {
// TODO Auto-generated constructor stub
}

/**
* 2014-10-25
*
* @author Qiuzhenping
* @param args [Parameters description]
* @return void [Return type description]
* @exception throws [Exception] [Exception description]
* @see [Related classes#Related methods#Related properties]
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
//Constructor[] contructor = Person.class.getConstructors();
//Method[] method = Person.class.getMethods();
Person p = new Person(24, "Qiuzhping", "100001", "Qiuzhping");
// Field [] field = p.getClass().getDeclaredFields();
// for(Field f:field){
// f.setAccessible(true);
// System.out.println(f.getName());
// Object obj = f.get(p);
// System.out.println(obj);
// }
changeStringValue(p);
System.out.println(p.toString());
callPersonSetNameMethod(p);
System.out.println(p.toString());
}

/**
* 通过调用Person类的setName方法将obj的name字段的Value设置为"callPersonSetNameMethod"来了解什么是Method反射

* 2014-10-26
*
* @author Qiuzhenping
* @param obj
* @throws Exception [Parameters description]
* @return void [Return type description]
* @exception throws [Exception] [Exception description]
* @see [Related classes#Related methods#Related properties]
*/
private static void callPersonSetNameMethod(Object obj) throws Exception {
Method[] methods = Person.class.getMethods();//获取全部方法
for(Method m : methods){
m.setAccessible(true);//暴力反射
if(m.getName().equals("setName")){
m.invoke(obj, "callPersonSetNameMethod");//将obj的name字段的Value设置为"callPersonSetNameMethod"
/**
* 以下是Java method关于invoke方法的源码
* 可以看到Method.invoke()实际上并不是自己实现的反射调用逻辑,而是委托给sun.reflect.MethodAccessor来处理。
* 真正的反射是调用MethodAccessor.invoke()真正完成反射调用。
* 看源码可以发现MethodAccessor.invoke() 方法中出现了很多跟Cached有关的变量,
* 说明method的反射十分消耗性能
* public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class caller = Reflection.getCallerClass(1);
Class targetClass = ((obj == null || !Modifier.isProtected(modifiers))
? clazz
: obj.getClass());

boolean cached;
synchronized (this) {
cached = (securityCheckCache == caller)
&& (securityCheckTargetClassCache == targetClass);
}
if (!cached) {
Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
synchronized (this) {
securityCheckCache = caller;
securityCheckTargetClassCache = targetClass;
}
}
}
}
if (methodAccessor == null) acquireMethodAccessor();
return methodAccessor.invoke(obj, args);
}
* */
}
}
}

/**
* 将obj对象中的String类型的字段对应的Value中含有i的字符替换为abc

* 2014-10-26
*
* @author Qiuzhenping
* @param obj [Parameters description]
* @return void [Return type description]
* @exception throws [Exception] [Exception description]
* @see [Related classes#Related methods#Related properties]
*/
private static void changeStringValue(Object obj) throws Exception {
Field[] fields = obj.getClass().getDeclaredFields();
for(Field f : fields){
f.setAccessible(true);//暴力反射
if(f.getType() == String.class){//字节码比较是用 ==
String oldValue = (String) f.get(obj);
String newValue = oldValue.replaceAll("i", "abc");//将所有的i替换为abc
f.set(obj, newValue);
}
}

}

static class Person {

public Person(int age, String name, String id, String pwd) {
super();
this.age = age;
this.name = name;
this.id = id;
this.pwd = pwd;
}
@Override
public String toString() {
return "age = "+age +"\tname = "+name+"\tid = "+id+"\tpwd = "+pwd;
}
private int age;
private String name;
private String id;
private String pwd;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
/**
*/
public Person() {
// TODO Auto-generated constructor stub
}

}

}

你可能感兴趣的:(Java 反射机制[Method反射])