文章目录
- 反射
- 1. 什么是反射
- 2. 获取class字段(字节码文件对象)
- 方式1
- 方式2
- 方式3
- 应用
- 3. 获取构造方法和权限修饰符
- 前期准备
- 获取所有的公共构造方法
- 获取所有的构造方法
- 获取无参构造方法
- 获取一个参数的构造方法
- 获取一个参数的构造方法
- 获取两个参数的构造方法
- 获取权限修饰符
- 获取参数的个数
- 获取构造方法中的所有参数
- 使用反射创建对象(暴力反射)
- 4. 获取成员变量
- 前期准备
- 获取公共成员变量
- 获取所有的成员变量
- 获取单个的成员变量
- 获取私有的单个成员变量
- 获取权限修饰符
- 获取成员变量名
- 获取成员变量的数据类型
- 获取成员变量记录的值
- 修改对象里面记录的值
- 5. 获取成员方法
- 前期准备
- 获取类里面所有的方法对象(包含父类中所有的公共方法)
- 获取类里面所有的方法对象(没有父类方法,但有本类中的私有方法)
- 获取类中的单个公共方法
- 获取类中的单个私有方法
- 获取方法的修饰符
- 获取方法的名字
- 获取方法的形参个数
- 获取方法的所有形参
- 获取方法抛出的异常
- 运行获取的方法
- 6. 反射的使用
- 获取对象信息并写入文件中
反射
1. 什么是反射
- 获取class对象
- 获取成员变量、构造方法、成员方法
- 获取各个关键字信息
2. 获取class字段(字节码文件对象)
方式1
Class.forName(“全类名”)
注意:此方法在源代码阶段,java文件编译成class文件的时候使用
方式2
类名.class
注意:此方法在加载阶段,运行代码前需要将class文件加载进入内存的时候
方式3
对象.getClass();
注意:此方法在程序的运行阶段使用
应用
package com.itchen.reflect;public class MyReflectDemo1 {public static void main(String[] args) throws ClassNotFoundException {Class clazz = Class.forName("com.itchen.reflect.Student");System.out.println(clazz);Class clazz2 = Student.class;System.out.println(clazz.equals(clazz2));Student s = new Student();Class clazz3 = s.getClass();System.out.println(clazz2.equals(clazz3));}
}
3. 获取构造方法和权限修饰符
前期准备
// 获取class对象
Class clazz = Class.forName("com.itchen.reflect.Student");
获取所有的公共构造方法
// 获取所有的公共构造方法
Constructor[] cons1 = clazz.getConstructors();
for(Constructor cos:cons1){System.out.println(cos);
}
获取所有的构造方法
// 获取所有的构造方法
Constructor[] cons2 = clazz.getDeclaredConstructors();
for (Constructor constructor : cons2) {System.out.println(constructor);
}
获取无参构造方法
// 获取无参构造方法
Constructor con1 = clazz.getDeclaredConstructor();
System.out.println(con1);
获取一个参数的构造方法
Constructor con2 = clazz.getDeclaredConstructor(String.class);
System.out.println(con2);
获取一个参数的构造方法
Constructor con3 = clazz.getDeclaredConstructor(int.class);
System.out.println(con3);
获取两个参数的构造方法
Constructor con4 = clazz.getDeclaredConstructor(String.class,int.class);
System.out.println(con4);
获取权限修饰符
int modifiers = con4.getModifiers();
System.out.println("权限修饰符字段为:"+modifiers);
获取参数的个数
int count = con4.getParameterCount();
System.out.println("参数个数为:"+count);
获取构造方法中的所有参数
Parameter[] parameters = con4.getParameters();
for (Parameter parameter : parameters) {System.out.println(parameter);
}
使用反射创建对象(暴力反射)
con4.setAccessible(true); // 临时取消权限校验
Student stu = (Student)con4.newInstance("张三", 24);
System.out.println(stu);
4. 获取成员变量
前期准备
// 获取class对象
Class clazz = Class.forName("com.itchen.reflect.Student");
获取公共成员变量
// 获取公共成员变量
Field[] fields = clazz.getFields();
for (Field field : fields) {System.out.println(field);
}
获取所有的成员变量
// 获取所有的成员变量
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {System.out.println(field);
}
获取单个的成员变量
Field gender = clazz.getField("gender");
System.out.println(gender);
获取私有的单个成员变量
Field name = clazz.getDeclaredField("name");
System.out.println(name);
获取权限修饰符
int modifiers = name.getModifiers();
System.out.println("此成员变量的权限修饰符为:"+modifiers);
获取成员变量名
String name1 = name.getName();
System.out.println("此成员变量的名字为:"+name1);
获取成员变量的数据类型
Class type = name.getType();
System.out.println("成员变量的类型为:"+type);
获取成员变量记录的值
name.setAccessible(true);// 临时取消访问权限
Student s = new Student("张三",32,"m");
String value = (String) name.get(s);
System.out.println(value);
修改对象里面记录的值
name.set(s,"李四");
System.out.println(s);
5. 获取成员方法
前期准备
// 获取class对象
Class clazz = Class.forName("com.itchen.reflect.Student");
获取类里面所有的方法对象(包含父类中所有的公共方法)
Method[] methods = clazz.getMethods();
for (Method method : methods) {System.out.println(method);
}
获取类里面所有的方法对象(没有父类方法,但有本类中的私有方法)
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {System.out.println(method);
}
获取类中的单个公共方法
Method m1 = clazz.getMethod("eat", String.class);
System.out.println(m1);
获取类中的单个私有方法
Method m2 = clazz.getDeclaredMethod("eat", String.class);
System.out.println(m2);
获取方法的修饰符
int modifiers = m2.getModifiers();
System.out.println("此方法的权限修饰符为"+modifiers);
获取方法的名字
String name = m2.getName();
System.out.println("此方法的名字是:"+name);
获取方法的形参个数
int count = m2.getParameterCount();
System.out.println("此方法的形参个数:"+count);
获取方法的所有形参
Parameter[] parameters = m2.getParameters();
for (Parameter parameter : parameters) {System.out.println(parameter);
}
获取方法抛出的异常
Class[] exceptionTypes = m2.getExceptionTypes();
for (Class exceptionType : exceptionTypes) {System.out.println(exceptionType);
}
运行获取的方法
Student s = new Student();
m2.setAccessible(true);
/*** 1. 方法的调用者* 2. 方法调用时传递的实际参数* */
m2.invoke(s,"薯条");
6. 反射的使用
获取对象信息并写入文件中
// Java文件(有业务逻辑)
package com.itchen.reflectTest;import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;public class MyReflectDemo {public static void main(String[] args) throws IllegalAccessException, IOException {Student s = new Student("xA",23,'w',167.5,"睡觉");Teacher t = new Teacher("Bn",1000);saveObject(t);}public static void saveObject(Object obj) throws IllegalAccessException, IOException {// 1. 获取字节码文件对象Class clazz = obj.getClass();// 2. 创建io流BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\icyler\\Desktop\\AndroidProject\\shiyan\\mydynamicproxy\\a.txt"));// 3. 获取所有的成员变量Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {field.setAccessible(true);// 获取成员变量的名字String name = field.getName();// 获取成员变量的值Object value = field.get(obj);bw.write(name + " = " + value);bw.newLine();}// 4. 关闭io流bw.close();}
}