java通过反射解决父类对象调用子类方法的问题-爱代码爱编程
业务场景:
最近做一个新增接口的需求,对接第三方报文时,发现该报文内容字段中,有多种子报文类型,且都是循环报文体,每种类型都有几个关键字段是相同的,需求需要拿到每个子报文的这几个关键字段进行处理。系统解析报文时,自动将相同类型的子报文解析为List<T>
集合,每个子报文解析为一个对象存储在集合中。例如:
//子报文解析得到的对象Demo1
public class Demo1{
private String id = "001"
private String name = "张三";
public String getName(){
return this.name;
}
public String getId(){
return this.id;
}
}
//子报文解析得到的对象Demo2
public class Demo2{
private String sex = "M";
private String name = "李四";
public String getSex(){
return this.sex;
}
public String getName(){
return this.name;
}
}
......
public class Test{
public static void main(String args[]){
//RespoBody为报文对象
//解析得到子报文对象(Demo1)集合
List<Demo1> demo1List = RespBody.getDemo1s();
//解析得到子报文对象(Demo2)集合
List<Demo2> demo2List = RespBody.getDemo2s();
......
}
}
问题描述:
此处只用两个Demo
类来举例,实际业务场景中有若干个这样的类(属性不完全相同)。此时要处理每个类的关键字段时(如name
),就需要将每个集合中的每个对象依次取出并处理,但我们知道,由于处理的字段是相同的,只有对象不同,我们当然会想到将处理字段的逻辑代码抽取成一个方法进行调用,我们只需要将集合作为参数传入方法即可。由于每个集合中保存的对象都是不同的类,所以在传参时集合需要使用泛型。
public class Test{
private void doData(List<?> list){
for(Object obj : list){
......
}
}
}
可以看到,由于使用了泛型参数,这样从集合中取出的对象就自动向上转型为了Object
类型,此时obj
对象作为原Demo
对象的父类对象,已经无法直接调用子类Demo
类的getName()
方法。
解决方案:
这里可以利用Java的反射机制,通过对象逆向的获取到类的信息,可以利用invoke()
方法调用Demo
类的方法。
public class Test{
private void doData(List<?> list){
for(Object obj : list){
obj.getClass().getMethod("getName").invoke(obj);
}
}
}
这里可以发现,invoke()
方法需要至少传入一个对象参数,作为调用前面获取到的getName()
方法的主体,而此时的obj
对象是Object
类型的,从表面上看,相当于我们通过一个父类对象,调用了子类对象的方法。
之前一直不太清楚反射机制的实际业务用途,今天碰到这个问题,经过学习后终于对反射有了更详细具体的了解。