关于如何通过反射调用指定的方法实践
一.背景
大致背景是这样的,我司有一个场景,通过调用RPC接口的方式查询得到一个实体,然后该实体中有多个属性,然后通过定义枚举的方式定义了实体的属性和对应的类型绑定起来,然后透传过去这个实体,通过if…else的方式来判断获取指定属性的值,这种背景下获取一两个属性还好一点,如果获取多个的话需要添加多个if…else,后续可能不是很好扩展,当然我们也可以用策略模式,这里主要使用的是反射。
二.什么是反射
1.概念:反射其实是一种机制,利用该机制可以在程序运行过程中对类进行解剖并操作类中的方法,属性,构造方法等成员.
2.获取反射的四种方式:
2.1 Class clazz = Student.class;
2.2 Class<? extends Student> clazz = new Student().getClass();
2.3 Class.forName(“com.ljm.reflect.test”),括号中的是该类的全限定类名
2.4通过当前线程的加载器获得:
Class<?> clz = Thread.currentThread().getContextClassLoader().loadClass(“com.ljm.reflect.test”);
3.反射的应用:
其实个人觉得反射最普遍的应用就是在Spring的代码中可以见到很多,还有就是一些序列化的组件也是通过反射来操作对象的,将对象中的一些属性转换成另外一个对象。
4.反射的缺点:
反射其实对性能是有影响,为什么会对性能有影响呢,首先当我们使用反射创建对象实例和方法时,我们需要创建大量的Class对象,以及构造器对象,这些对象都是临时对象会造成GC,我们都知道GC的频繁的话对应用是会有影响的。还有就是我们调用方法时是需要遍历数组获取的在时间上也会有一点消耗。
三.如何通过反射调用指定方法获取对象的属性实践
3.1 Student对象
package com.ljm;/**
* @Author LJM
* @Date 2021/11/7 12:28
* @Version 1.0
*/
/**
* @ClassName Student
* @Description 学生对象测试
* @Author ljm
* @Date 12:28 2021/11/7
* @Version 2.1
**/
public class Student {
private Integer id;
private String address;
private String name;
private String hobby;
private String gender;
public Student(Integer id, String address, String name, String hobby, String gender) {
this.id = id;
this.address = address;
this.name = name;
this.hobby = hobby;
this.gender = gender;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", address='" + address + '\'' +
", name='" + name + '\'' +
", hobby='" + hobby + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
3.2测试类
package com.ljm;/**
* @Author LJM
* @Date 2021/11/7 12:35
* @Version 1.0
*/
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @ClassName ReflectTest
* @Description 反射测试
* @Author ljm
* @Date 12:35 2021/11/7
* @Version 2.1
**/
public class ReflectTest {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
//获取字节码对象
Class<Student> clazz = Student.class;
Student student = new Student(1, "江西上饶", "ljm", "篮球", "男");
Object fieldTest = getAttributesByReflect(clazz, "getId",student);
System.out.println(field);
}
protected static Object getAttributesByReflect(Class<Student> clazz, String methodName, Student student) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method method = clazz.getMethod(methodName, null);
//设置暴力破解
method.setAccessible(true);
return method.invoke(student);
}
}
3.3 当我们需要调用私有的成员方法时我们只需要去将相应的属性设置成暴力破解即可获取.
四.总结
其实反射怎么说呢有很多使用方式,我呢写博客不是为了给别人看只是简单记录一下,要往深了研究还得多实践,多看书,最起码你得知道有这个东西,希望未来自己越来越好,加油,写不动了因为我要去打球了哈哈哈,篮球是个好东西,越用力他弹的越高,学习也是个好东西,越努力越幸运!