Java反射机制学习笔记

来源:互联网 发布:南京域名备案中心 编辑:程序博客网 时间:2024/05/17 23:13

Java反射机制:

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

示例类

package reflect;public class Hello {private String name;public Hello() {super();}public Hello(String name) {super();this.name = name;}public void sayHello() {System.out.println((name == null ? "" : name) + " say hello");}public void sayHello(String toSomeOne) {System.out.println((name == null ? "" : name) + " say hello to "+ toSomeOne);}public String getName() {return name;}public void setName(String name) {this.name = name;}}


实例化Class类的三种方式

java程序运行时,所有的java类在JVM中都表现为java.lang.Class类的实例化对象。
/* * 获取class三种方式 *///helloClass表示Hello类的类类型(class type)//1.Class.forName(类的全称),运行时动态加载类Class<?> helloClass=Class.forName("reflect.Hello");//2.类的对象.getClass()Hello hello=new Hello();Class<?> helloClass2 = hello.getClass();//3.类.classClass<?> helloClass3=Hello.class;

获取类中方法信息

/** * 打印类中方法信息 *  * @param clazz */public static void printClassMethodsMessage(Class<?> clazz) {// 获取类的名称System.out.println("类的名称是:" + clazz.getName());/* * 获取类的方法 一个方法对应一个Method对象 getMethods()获取所有public修饰的方法(包括从父类中继承的方法) * getDeclaredMethods()获取所有在该类声明的方法 */Method[] methods = clazz.getDeclaredMethods();System.out.println("类中包含方法:");for (Method method : methods) {// 获取返回类型Class<?> returnType = method.getReturnType();System.out.print(returnType.getName() + " ");// 打印方法名System.out.print(method.getName());System.out.print("(");// 获取参数类型Class<?>[] parameterTypes = method.getParameterTypes();for (Class<?> cls : parameterTypes) {System.out.print(cls.getName() + ",");}System.out.println(")");}}

获取类中成员变量信息

/** * 打印类中成员变量信息 *  * @param clazz */public static void printClassFieldsMessage(Class<?> clazz) {// 获取类的名称System.out.println("类的名称是:" + clazz.getName());/* * 获取类中的成员变量 一个成员变量对应一个Field对象 * getFields()获取类中所有public修饰的成员变量(包括从父类继承的成员变量) * getDeclaredFields()获取类中声明的所有成员变量 */Field[] fields = clazz.getDeclaredFields();System.out.println("类中包含成员变量:");for (Field field : fields) {// 获取变量类型Class<?> type = field.getType();// 获取变量名称String fieldName = field.getName();System.out.println(type.getName() + " " + fieldName);}}

获取类中构造函数信息

/** * 打印构造方法信息 * @param clazz */public static void printClassConstructorMessage(Class<?> clazz) {// 获取类的名称System.out.println("类的名称是:" + clazz.getName());/* * 获取构造方法 一个构造方法对应一个Constructor对象 * getConstructors()获取所有public修饰的构造方法(包括从父类继承的构造方法) * getDeclaredConstructors()获取所有类中声明的构造方法 */Constructor<?>[] constructors = clazz.getDeclaredConstructors();System.out.println("类中构造方法:");for (Constructor<?> constructor : constructors) {// 构造方法名System.out.print(constructor.getName() + "(");// 获取构造方法参数Class<?>[] parameterTypes = constructor.getParameterTypes();for (Class<?> cls : parameterTypes) {System.out.print(cls.getName());}System.out.println(")");}}

调用某方法

/** * 通过反射调用某方法 *  * @param clazz *            类类型 * @param methodName *            方法名 * @param parameterTypes *            方法参数类型 * @param args *            方法传入参数 */public static Object methodInvoke(Class<?> clazz, String methodName,Class<?>[] parameterTypes, Object[] args) {Object res = new Object();try {// 通过方法名、参数类型可以确定唯一的成员方法Method method = clazz.getMethod(methodName, parameterTypes);res = method.invoke(clazz.newInstance(), args);} catch (Exception e) {e.printStackTrace();}return res;}

改变成员变量值

/** * 通过反射改变对象变量值 * @param obj *            需要改变成员变量值的对象 * @param fieldName *            需要改变的成员变量名 * @param value *            改变成员变量的值 */public static synchronized void changeFieldValue(Object obj,String fieldName, Object value) {try {Class<?> clazz = obj.getClass();// 获取成员变量Field field = clazz.getDeclaredField(fieldName);// 成员变量设置为可修改field.setAccessible(true);// 修改成员变量值field.set(obj, value);// 成员变量设置为不可修改field.setAccessible(false);} catch (Exception e) {e.printStackTrace();}}

测试类

package reflect;public class Test {public static void main(String[] args) throws ClassNotFoundException {/* * 获取class三种方式 *///helloClass表示Hello类的类类型(class type)//1.Class.forName(类的全称),运行时动态加载类Class<?> helloClass=Class.forName("reflect.Hello");////2.类的对象.getClass()//Hello hello=new Hello();//Class<?> helloClass2 = hello.getClass();//////3.类.class//Class<?> helloClass3=Hello.class;ClassUtil.printClassMethodsMessage(helloClass);System.out.println("=========================");ClassUtil.printClassFieldsMessage(helloClass);System.out.println("=========================");ClassUtil.printClassConstructorMessage(helloClass);System.out.println("=========================");Class<?>[] parameterTypes1 ={};Object[] args1={};System.out.println("调用sayHello():");ClassUtil.methodInvoke(helloClass, "sayHello", parameterTypes1, args1);System.out.println("=========================");Class<?> [] parameterTypes2={String.class};Object[] args2={"tom"};System.out.println("调用sayHello(String name):");ClassUtil.methodInvoke(helloClass, "sayHello", parameterTypes2, args2);System.out.println("=========================");System.out.println("通过反射改变name值:");Hello hello=new Hello("tom");hello.sayHello();ClassUtil.changeFieldValue(hello, "name", "jerry");hello.sayHello();System.out.println("=========================");}}

运行结果



参考资料:慕课网:反射——Java高级开发必须懂的
^ ^ 欢迎批评指正

0 0
原创粉丝点击