反射
现实生活中有很多反射的例子,比如医院里面的X射线,西游记里面的照妖镜等,可以看出反射其实具有透视的作用,可以透视一个类,透视一个对象
反射的官方定义:在程序运行的过程中,可以动态的创建对象,并获取对象的基本信息,包括属性、方法等;
在运行时去获取一个类的变量和方法信息,然后通过获取到的信息来创建对象,调用方法的一种机制
获取class类的对象
要通过反射去使用一个类,要先获得类型为Class类型的对象
反射获取构造方法-Constructor
//先获取类的反射对象
Class<?> c1 = Class.forName("streamliu.student");
//获取反射的构造方法
Constructor<?> con1 = c1.getConstructor(String.class, int.class, String.class);
//创建反射的对象
Object o1 = con1.newInstance("sss", 22, "ds");
System.out.println(o1);
Constructor<?> decon = c1.getDeclaredConstructor(String.class);
//对于访问有限制的对象,用setAccessible值为true时,会取消访问检查
decon.setAccessible(true);
Object obj2 = decon.newInstance("dds");
System.out.println(obj2);
反射获取成员变量-Field
//先获取类的反射对象
Class<?> c1 = Class.forName("streamliu.student");
获取反射的所有成员方法
Field[] fields = c1.getDeclaredFields();
for(Field field : fields){
System.out.println(field);
}
//获取反射的构造方法
Constructor<?> con = c1.getConstructor();
//创建反射的对象
Object obj = con.newInstance();
System.out.println(obj);
//反射获取成员变量
Field namefield = c1.getField("name");
//访问非public的成员变量
namefield.setAccessible(true);
//给成员变量赋值
namefield.set(obj,"haah");
Field agefield = c1.getField("age");
agefield.set(obj,10);
Field locationfield = c1.getField("location");
locationfield.set(obj,"shanghai");
//打印输出成员变量值
System.out.println(namefield.get(obj));
System.out.println(agefield.get(obj));
System.out.println(locationfield.get(obj));
反射获取成员方法-Mehtod
//获取反射的所有的public成员方法
Method[] methods = c1.getMethods();
//获取反射的所有包括private的成员方法
Method[] declaredMethods = c1.getDeclaredMethods();
for(Method method:declaredMethods){
System.out.println(method);
}
//获取反射的指定名称的成员方法
Method m1 = c1.getMethod("method1");
//反射调用成员方法
m1.invoke(obj);
Method[] methods = c1.getMethods();
Method[] declaredMethods = c1.getDeclaredMethods();
for(Method method:declaredMethods){
System.out.println(method);
}
//带参数的成员方法
Method m2 = c1.getMethod("method2", String.class);
m2.invoke(obj,"yoyo");
Method m3 = c1.getMethod("method3", String.class, int.class);
//对象接收带返回值的参数并打印
Object obj3 = m3.invoke(obj, "yoyo", 30);
System.out.println(obj3);
//private修饰的成员方法
Method m4 = c1.getDeclaredMethod("function");
m4.setAccessible(true);
m4.invoke(obj);
反射可以越过泛型检查,直接在集合中添加数据
用反射运行配置文件指定内容
//载入配置文件
Properties prop = new Properties();
FileReader fr = new FileReader("stream/peizhi.txt");
prop.load(fr);
fr.close();
//配置文件内容
/* className=stream/student
methodName=study*/
//将载入内容赋值取数,以便后续调用
//之后只需要修改配置文件,不用涉及源代码就可以调整配置
String className = prop.getProperty("className");
String methodName = prop.getProperty("methodName");
Class<?> c = Class.forName(className);
Constructor<?> con = c.getConstructor();
Object obj = con.newInstance();
Method m = c.getMethod(methodName);
m.invoke(obj);