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反射机制浅析的主要内容,如果未能解决你的问题,请参考以下文章