标签:getconstructor newinstance getdeclaredmethod invoke 反射
反射(reflective)是指能够分析类的能力的程序。
反射库(reflection library)提供了一个非常丰富且精心设计的工具集,以便编写能够动态操作Java代码的程序。
程序运行期间,Java运行时系统始终未所有的对象维护一个被称为运行时的类型标识。这个信息跟踪着每个对象所属的类。虚拟机利用运行时信息选择相应的方法执行。
Class 反射对象描述类的语义结构,可以从Class对象中获取构造函数、成员变量、方法等元素的反射对象,并以编程的方式通过这些反射对象对目标类对象进行操作。这些反射对象类定义在java.reflect包中,包含Constructor,Method 和 Field。
部分反射功能在上一篇博文
证明接口interface中的方法访问权限为public 已经做过示例,这里就不再做叙述,这里只讲没有讲到的部分,不了解的朋友,可以先查看上一篇博文。
package com.zhangqi.reflect; public class Car { private String id; private String name; private int maxSpeed; public Car() {}; public Car(String id, String name, int maxSpeed) { this.id = id; this.name = name; this.maxSpeed = maxSpeed; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getMaxSpeed() { return maxSpeed; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } // 重写toString方法,输出可读的对象属性数据 public String toString() { return "id=" + this.id + ",name=" + this.name + ",maxSpeed=" + this.maxSpeed; } }
测试代码
package com.zhangqi.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class CarReflect { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { Class<?> clazz = Class.forName("com.zhangqi.reflect.Car"); // 获取构造函数数组 Constructor<?>[] cons = clazz.getConstructors(); System.out.println("分割线-- 下面的为构造函数--"); // 遍历构造函数数组 for (Constructor<?> con : cons) { System.out.println(con); } System.out.println("分割线-- 下面为有参的构造函数--"); // 获取指定参数类型的构造方法 Constructor<?> conInArgs = clazz.getConstructor(String.class, String.class, int.class); System.out.println(conInArgs); // 调用newInstance 方法构造对象 Car car1 = (Car) conInArgs.newInstance("001", "Audi", 210); System.out.println("分割线-- 下面打印car1 对象"); System.out.println(car1); // 获取无参的构造方法 Constructor<?> conNoArgs = clazz.getConstructor((Class<?>[])null); Car car2 = (Car) conNoArgs.newInstance((Object[])null); // 获取特定签名的方法 // 依次获取setId方法、setName方法、setMaxSpeed方法 Method setId = clazz.getDeclaredMethod("setId", String.class); System.out.println("分割线-- 下面输出的是setId方法"); System.out.println(setId); Method setName = clazz.getDeclaredMethod("setName", String.class); Method setMaxSpeed = clazz.getDeclaredMethod("setMaxSpeed", int.class); // 通过调用invoke方法,给car2 赋属性值 setId.invoke(car2, "002"); setName.invoke(car2, "Volvo"); setMaxSpeed.invoke(car2, 240); System.out.println("分割线 -- 下面打印通过方法赋值后的car2对象"); System.out.println(car2); // 获取getId方法 Method getId = clazz.getDeclaredMethod("getId", (Class<?>[])null); System.out.println("分割线 -- 下面输出getId方法的返回值类型"); // 获取方法的返回值类型 System.out.println(getId.getReturnType()); System.out.println("分割线-- 下面输出有参构造函数的参数类型"); // 获取方法的入参类型数组 Class<?>[] parameterTypes = conInArgs.getParameterTypes(); for (Class<?> cla : parameterTypes) { System.out.println(cla); } System.out.println("分割线-- 下面输出成员变量id"); // 获取某个特定名称的成员变量反射对象 Field id = clazz.getDeclaredField("id"); System.out.println(id); id.setAccessible(true); // Exception in thread "main" java.lang.IllegalAccessException: Class com.zhangqi.reflect.CarReflect can not access a member of class com.zhangqi.reflect.Car with modifiers "private" id.set(car2, "id002"); System.out.println("分割线-- 下面输出通过成员变量赋值方式修改过的对象"); System.out.println(car2); } }
分割线-- 下面的为构造函数-- public com.zhangqi.reflect.Car() public com.zhangqi.reflect.Car(java.lang.String,java.lang.String,int) 分割线-- 下面为有参的构造函数-- public com.zhangqi.reflect.Car(java.lang.String,java.lang.String,int) 分割线-- 下面打印car1 对象 id=001,name=Audi,maxSpeed=210 分割线-- 下面输出的是setId方法 public void com.zhangqi.reflect.Car.setId(java.lang.String) 分割线 -- 下面打印通过方法赋值后的car2对象 id=002,name=Volvo,maxSpeed=240 分割线 -- 下面输出getId方法的返回值类型 class java.lang.String 分割线-- 下面输出有参构造函数的参数类型 class java.lang.String class java.lang.String int 分割线-- 下面输出成员变量id private java.lang.String com.zhangqi.reflect.Car.id 分割线-- 下面输出通过成员变量赋值方式修改过的对象 id=id002,name=Volvo,maxSpeed=240
代码讲解
Car car1 = (Car) conInArgs.newInstance("001", "Audi", 210);构造一个Car 对象出来,这里使用newInstance 方法,相当于new 关键字,同时传递相应入参进去。
// 获取方法的入参类型数组 Class<?>[] parameterTypes = conInArgs.getParameterTypes(); for (Class<?> cla : parameterTypes) { System.out.println(cla); }
这里的输出结果中
class java.lang.String class java.lang.String int前面两个String 对应的是id 和 name的类型,最后的int 是基础类型,所以是单的int
id.setAccessible(true); id.set(car2, "id002");这里必须要id.setAccessible(true); 因为id为private类型,必须先将其设置为可访问,否则抛出异常
Exception in thread "main" java.lang.IllegalAccessException: Class com.zhangqi.reflect.CarReflect can not access a member of class com.zhangqi.reflect.Car with modifiers "private"
标签:getconstructor newinstance getdeclaredmethod invoke 反射
原文地址:http://blog.csdn.net/magi1201/article/details/45788715