• 信步拾遗之Java反射机制浅析


    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    “程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

    Java反射机制主要相关的类:
    java.lang.Class;
    java.lang.reflect.Constructor;
    java.lang.reflect.Field;
    java.lang.reflect.Method;
    java.lang.reflect.Modifier;

    Java中获取Class有三种方式(以UserBean类为例):
    1、类名.class
    UserBean.class
    2、对象.getClass();
    UserBean userBean = new UserBean();
    userBean.getClass();
    3、Class.forName()
    Class.forName("com.alfred.bean.UserBean");
    如果是在同级目录下可以不加路径

    需要解释一点就是,java中一切都是对象,我们获取的Class也是一个对象。基本类型int、float等也会在jvm的内存池像其他类型一样生成一个Class对象。而数组等组合型数据类型也是会生成一个Class对象的,而且更令人惊讶的是,java中数组的本来面目其实就是某个类。
    例如:
    Class c1 = int.class;
    Class c2 = Double[].class;

    通过使用java反射机制可以实现:
    1、运行时获取类结构(包括类名,修饰符,属性,方法,构造函数,父类,接口等等)
    2、运行时调用类公共方法(可以传递方法参数)
    3、运行时创建类对象

    以下是java反射机制的实例:

    package com.alfred.main;
    
    import java.lang.reflect.Array;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    
    public class Reflection {
    
        /**
         * 打印整个类的结构(包括父子类接口)
         * @param c Class对象
         */
        public static void printClassStructure(Class c) {
            try {
                // 获取所有的属性(不包括父类的)
                Field[] fs = c.getDeclaredFields();
    
                // 定义可变长的字符串,用来存储属性
                StringBuffer sb = new StringBuffer();
                // 通过追加的方法,将每个属性拼接到此字符串中
                // 最外边的public定义
                sb.append(Modifier.toString(c.getModifiers()) + " class "
                        + c.getSimpleName());
                Class superclass = c.getSuperclass();
                if (superclass != null && !superclass.getSimpleName().equals("Object")) {
                    // 不是直接继承于Object,说明有其他继承类
                    printClassStructure(superclass);
                    sb.append(" extends " + superclass.getSimpleName());
                }
                Class[] interfaces = c.getInterfaces();
                if (interfaces.length > 0) {
                    sb.append(" implements ");
                    for (int i = 0; i < interfaces.length; i++) {
                        printClassStructure(interfaces[i]);
                        sb.append(((i != 0) ? "," : "")
                                + interfaces[i].getSimpleName());
                    }
                }
                sb.append("{
    ");
    
                // 类中的属性
                for (Field field : fs) {
                    sb.append("	");// 缩进
                    sb.append(Modifier.toString(field.getModifiers()) + " ");// 获得属性的修饰符,例如public,static等等
                    sb.append(field.getType().getSimpleName() + " ");
                    sb.append(field.getName() + ";
    ");
                }
    
                // 类中的构造方法
                Constructor[] declaredConstructors = c.getDeclaredConstructors();
                for (Constructor constructor : declaredConstructors) {
                    sb.append("	");
                    sb.append(Modifier.toString(constructor.getModifiers()) + " ");
                    sb.append(c.getSimpleName() + "(");
                    Class[] parameterTypes = constructor.getParameterTypes();
                    for (int i = 0; i < parameterTypes.length; i++) {
                        sb.append(((i != 0) ? "," : "")
                                + parameterTypes[i].getSimpleName() + " arg" + i);
                    }
                    sb.append("){}
    ");
                }
    
                // 类中的方法
                Method[] ms = c.getDeclaredMethods();
                for (Method method : ms) {
                    sb.append("	");
                    sb.append(Modifier.toString(method.getModifiers()) + " ");
                    sb.append(method.getReturnType().getSimpleName() + " ");
                    sb.append(method.getName() + "(");
                    Class<?>[] parameterTypes = method.getParameterTypes();
                    for (int i = 0; i < parameterTypes.length; i++) {
                        sb.append(((i != 0) ? "," : "")
                                + parameterTypes[i].getSimpleName() + " arg" + i);
                    }
                    sb.append("){}
    ");
                }
    
                sb.append("}");
    
                System.out.println(sb);
                System.out.println("=================================");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 得到某个对象的公共属性
         * @param owner
         * @param fieldName
         * @return 该属性对象
         * @throws Exception
         */
        public static Object getProperty(Object owner, String fieldName)
                throws Exception {
            Class ownerClass = owner.getClass();
            Field field = ownerClass.getDeclaredField(fieldName);
            Object property = field.get(owner);
            return property;
        }
    
        /**
         * 得到某类的静态公共属性
         * @param className 类名
         * @param fieldName 属性名
         * @return 该属性对象
         * @throws Exception
         */
        public static Object getStaticProperty(String className, String fieldName)
                throws Exception {
            Class ownerClass = Class.forName(className);
            Field field = ownerClass.getField(fieldName);
            Object property = field.get(ownerClass);
            return property;
        }
    
        /**
         * 执行某对象方法
         * @param owner 对象
         * @param methodName 方法名
         * @param args 参数
         * @return 方法返回值
         * @throws Exception
         */
        public static Object invokeMethod(Object owner, String methodName, Object[] args)
                throws Exception {
            Class ownerClass = owner.getClass();
            Class[] argsClass = new Class[args.length];
            for (int i = 0, j = args.length; i < j; i++) {
                argsClass[i] = args[i].getClass();
            }
            Method method = ownerClass.getMethod(methodName, argsClass);
            return method.invoke(owner, args);
        }
    
        /**
         * 执行某类的静态方法
         * @param className 类名
         * @param methodName 方法名
         * @param args 参数数组
         * @return 执行方法返回的结果
         * @throws Exception
         */
        public static Object invokeStaticMethod(String className, String methodName,
                Object[] args) throws Exception {
            Class ownerClass = Class.forName(className);
            Class[] argsClass = new Class[args.length];
            for (int i = 0, j = args.length; i < j; i++) {
                argsClass[i] = args[i].getClass();
            }
            Method method = ownerClass.getMethod(methodName, argsClass);
            return method.invoke(null, args);
        }
    
        /**
         * 新建实例
         * @param className 类名
         * @param args 构造函数的参数
         * @return 新建的实例
         * @throws Exception
         */
        public static Object newInstance(String className, Object[] args) throws Exception {
            Class newClass = Class.forName(className);
            Class[] argsClass = new Class[args.length];
            for (int i = 0, j = args.length; i < j; i++) {
                argsClass[i] = args[i].getClass();
            }
            Constructor cons = newClass.getConstructor(argsClass);
            return cons.newInstance(args);
        }
    
        /**
         * 是不是某个类的实例
         * @param obj 实例
         * @param cls 类
         * @return 如果 obj 是此类的实例,则返回 true
         */
        public static boolean isInstance(Object obj, Class cls) {
            return cls.isInstance(obj);
        }
    
        /**
         * 得到数组中的某个元素
         * @param array 数组
         * @param index 索引
         * @return 返回指定数组对象中索引组件的值
         */
        public static Object getByArray(Object array, int index) {
            return Array.get(array, index);
        }
    
    }
  • 相关阅读:
    hiho47 : 拓扑排序·一
    Excel 曝Power Query安全漏洞
    分布式系统技术:存储之数据库
    队列应用
    20155239《Java程序设计》实验一(Java开发环境的熟悉)实验报告
    打印Java main方法执行的命令参数代码
    nothing to commit, working tree clean Remote "origin" does not support the LFS locking API. Consider disabling it with:
    异步
    字节跳动杨震原:A/B测试不是万能的,但不会一定不行
    集成显卡 独显
  • 原文地址:https://www.cnblogs.com/alfredinchange/p/5325062.html
Copyright © 2020-2023  润新知