zoukankan      html  css  js  c++  java
  • Java 反射机制[Method反射]

    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 +" name = "+name+" id = "+id+" pwd = "+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
            }

        }

    }

  • 相关阅读:
    dayjs:js时间插件
    IE:IE请求路径带中文报错
    layui:下载表格为excel文件
    VUE:导出表格为excel文件
    报错:unexpected trailing comma
    node.js报错address not available 192.168.1.4
    js防抖和节流
    mongodb的常用基础命令及操作
    mongodb下载安装及环境搭建
    vue页面缓存
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4215515.html
Copyright © 2011-2022 走看看