Java反射机制浅析

Posted 临渊启明

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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("{\n");

            // 类中的属性
            for (Field field : fs) {
                sb.append("\t");// 缩进
                sb.append(Modifier.toString(field.getModifiers()) + " ");// 获得属性的修饰符,例如public,static等等
                sb.append(field.getType().getSimpleName() + " ");
                sb.append(field.getName() + ";\n");
            }

            // 类中的构造方法
            Constructor[] declaredConstructors = c.getDeclaredConstructors();
            for (Constructor constructor : declaredConstructors) {
                sb.append("\t");
                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("){}\n");
            }

            // 类中的方法
            Method[] ms = c.getDeclaredMethods();
            for (Method method : ms) {
                sb.append("\t");
                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("){}\n");
            }

            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);
    }

}

以上是关于Java反射机制浅析的主要内容,如果未能解决你的问题,请参考以下文章

java反射机制浅析

java中的反射机制浅析

JAVA中的反射机制理解与浅析

反射机制

动态代理之JDK Proxy浅析

反射机制入门