反射操作使用案例分析
1.反射的概念
1.什么是反射
对于java文件编译形成的.class二进制文件,它们具有成员属性、构造方法、成员方法这些特征。根据面向对象的思想,万物皆为对象,因此,可以将class文件看作一个类型,每一个.class文件则作为Class类的实例化对象。
java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
2.反射相关类
class类 ->代表类的实体
Field类 -> 代表类的成员变量
Method类->代表类的方法
Constructor类 ->代表类的构造方法
3.反射相关方法
3.1 获取class类相关方法
Class Class.forName(String packageNameAndClassName) throws ClassNotFoundException;
Class 类对象.getClass();
Class 类名.class;
3.2 获取Constructor相关方法以及Constructor类方法
//获取当前class对象对应类中所有非私有化构造方法类对象数组
Constructor[] getConstructors();
//获取当前class对象对应类中所有构造方法类对象数组
Constructor[] getDeclardConstructors();
//获取当前class对象指定参数数据类型的构造方法,不包含私有化方法
Constructor getConstructor(Class... parameterTypes);
//获取当前class对象指定参数数据类型的构造方法,包含私有化方法
Constructor getDeclardConstructor(Class... paramererTypes);
//通过Constructor类对象创建对应类对象
Object newInstance(Object... parameters);
3.3 获取Method相关方法以及Method类方法
//获取当前类内的所有非私有化成员方法,包含从父类继承的非私有化方法
Method[] getMethods();
//获取当前类内的所有成员方法
Method[] getDeclareMethods();
//获取当类内指定方法名称和参数类型的非私有化成员方法 包含从父类继承的非私有化方法
Method getMethods(String methodName,Class...parametertypes);
//获取当类内指定方法名称和参数类型的成员方法
Method getDeclareMethods(String methodName,Class...parametertypes);
//通过Method类对象调用,执行对应方法
Object invoke(Object obj, Object... parameters);
3.4 获取Feild相关方法
//获取类内所有非私有化成员变量对象数组
Field[] getFields();
//获取类内所有成员变量对象数组
Field[] getDeclaredFields();
//根据变量名字获取对应的非私有化成员变量对象
Field getField(String fieldName);
//根据变量名字获取对应的成员变量对象
Field getDeclaredField(String fieldName);
//通过Feild对象给对应obj对象的Feild属性赋值
void set(Object obj, Object value);
//通过Feild对象获取对应obj对象的Feild属性值
Object get(Object obj);
//获取Feild类对象对应的数据类型
getClassType();
3.5暴力反射授权方法
class AccessibleObject 类内方法
public static void setAccessible(AccessibleObject[] array, boolean flag);
通过类名调用的静态工具方式,给予AccessibleObject类对象或者其子类对象数组,赋值操作权限。
子类对象包括: Field Method Constructor
public void setAccessible(boolean flag);
通过AccessibleObject类对象调用,单一权限授权,Field Method Constructor都可以使用。
4.反射使用实例
将文件中的数据读取到对应类对象中
student.txt文件
className=com.mytest.Student
name=张三
age=18
gender=0
//1. 创建缓冲字符输入流
BufferedReader br = new BufferedReader(new FileReader("student.txt"));
// 2. 读取文件数据
String classInfo = br.readLine();
String className = classInfo.substring(classInfo.indexOf("=") + 1);
// 3. 启动万恶之源 获取Class对象,加载指定类
Class cls = Class.forName(className);
// 4. 创建对应类对象
Object obj = cls.getConstructor().newInstance();
// 5. 读取文件,利用循环操作
String info = null;
Object value = null;
// 每一次从文件中读取一行数据
while ((info = br.readLine()) != null) {
// 按照 = 分割信息
String[] split = info.split("=");
System.out.println(Arrays.toString(split));
// 根据信息获取对应成员变量对象
Field field = cls.getDeclaredField(split[0]);
field.setAccessible(true);
// 获取成员变量数据类型
Class type = field.getType();
// 当前成员变量数据为String类型
if (type.equals(String.class)) {
value = split[1];
// 成员变量数据类型为int类型
} else if (type.equals(int.class)) {
value = Integer.parseInt(split[1]);
// 成员变量数据类型为boolean类型
} else if (type.equals(boolean.class)) {
value = Boolean.parseBoolean(split[1]);
}
field.set(obj, value);
}
System.out.println(obj);
// 关闭资源
br.close();