Java 反射机制[Method反射]

2022-12-07,,,

Java 反射机制[Method反射]

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

能够看到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

        }

    }

}

Java 反射机制[Method反射]的相关教程结束。

《Java 反射机制[Method反射].doc》

下载本文的Word格式文档,以方便收藏与打印。