Java 反射机制[Method反射]

来源:互联网 发布:哈萨克软件下载大全 编辑:程序博客网 时间:2024/05/17 01:23

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   :  <description>
*/

/* Updation record 1:
 * Updation date        :  2014-10-25
 * Updator          :  Qiuzhenping
 * Trace No:  <Trace No>
 * Updation No:  <Updation No>
 * Updation Content:  <List all contents of updation and all methods updated.>
 */
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;


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

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

    /** <Description functions in a word>
     * 2014-10-25
     * <Detail description>
     * @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());
    }

    /** <Description functions in a word>
     *  通过调用Person类的setName方法将obj的name字段的Value设置为"callPersonSetNameMethod"来了解什么是Method反射<BR>
     *  2014-10-26
     * <Detail description>
     * @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);
                }
                 * */
            }
        }
    }

    /** <Description functions in a word>
     *  将obj对象中的String类型的字段对应的Value中含有i的字符替换为abc<BR>
     *  2014-10-26
     * <Detail description>
     * @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;
        }
        /** <default constructor>
         */
        public Person() {
            // TODO Auto-generated constructor stub
        }

    }

}

0 0
原创粉丝点击