上篇文章介绍了反射当前类、父类、非基本类型、泛型类、内部类的私有属性,本篇文章分享当被反射类含有静态内部类的情况下,如何反射其私有属性。
首先,我们仍然建立User类,一个含有静态类的User:
import lombok.Data;
import java.util.List;
@Data
public class User6 {
private Long id;
private String name;
private String descr;
//持有静态内部类属性,用于获取静态内部类数据
private List<Item> itemList;
@Data
public static class Item{
private String itemName;
}
}
此次示例中,类中不仅含有静态内部类,并且含有list数据。我们不仅要反射静态内部类,而且要反射list数据。
相关反射示例代码如下:
public void reflectClassWithList(Object object,Class clazz){
try {
for (Field field:clazz.getDeclaredFields()){
//设置可访问属性
field.setAccessible(true);
// log.info("modifier:{}",field.getModifiers());
Object fieldValue = field.get(object);
if (fieldValue != null && !isBaseType(fieldValue)){
if (fieldValue instanceof List){
for (int i = 0; i < ((List<?>) fieldValue).size(); i++) {
Object listSubObject = ((List<?>) fieldValue).get(i);
reflectClassWithList(listSubObject, listSubObject.getClass());
}
}else {
reflectClassWithList(fieldValue,fieldValue.getClass());
}
}
log.info("fieldName:{},fieldValue:{}",field.getName(),fieldValue);
}
}catch (Exception e){
e.printStackTrace();
}
}
对于list类型,我们判断是否属于List类型,然后对其进行解析,解析过后,就跟普通实体反射一样了。
下面看下测试方法:
private static void testUser6(){
log.info("test 反射获取静态内部类的私有属性 start ..");
User6 user6 = new User6();
user6.setName("perry");
//静态内部类
List<User6.Item> items = Lists.newArrayList();
User6.Item item = new User6.Item();
item.setItemName("new item");
items.add(item);
user6.setItemList(items);
ReflectClass reflectClass = new ReflectClass();
//注意调用对象
reflectClass.reflectClassWithList(user6, User6.class);
log.info("test 反射获取静态内部类的私有属性 end ..");
}
输出如下:
13:49:33.703 [main] INFO com.perry.reflect.test.ReflectClass - test 反射获取静态内部类的私有属性 start ..
13:49:33.711 [main] INFO com.perry.reflect.test.ReflectClass - fieldName:id,fieldValue:null
13:49:33.713 [main] INFO com.perry.reflect.test.ReflectClass - fieldName:name,fieldValue:perry
13:49:33.713 [main] INFO com.perry.reflect.test.ReflectClass - fieldName:descr,fieldValue:null
13:49:33.713 [main] INFO com.perry.reflect.test.ReflectClass - fieldName:itemName,fieldValue:new item
13:49:33.713 [main] INFO com.perry.reflect.test.ReflectClass - fieldName:itemList,fieldValue:[User6.Item(itemName=new item)]
13:49:33.713 [main] INFO com.perry.reflect.test.ReflectClass - test 反射获取静态内部类的私有属性 end ..
以上代码,可以看到,静态内部类,以及List属性,进行了反射。
回顾上一篇,讲反射内部类的例子,我们可以对其进行改写,以使主类持有内部类的属性,这样就可以访问到内部类的属性了。我们来试下。
含有普通内部类的User修改如下:
import lombok.Data;
@Data
public class User7 {
private Long id;
private String name;
private String descr;
private Role role;
@Data
class Role {
private String roleName;
}
}
反射方法:
public void reflectClassWithNewInnerClass(Object object,Class clazz){
try {
for (Field field:clazz.getDeclaredFields()){
//设置可访问属性
field.setAccessible(true);
// log.info("modifier:{}",field.getModifiers());
Object fieldValue = field.get(object);
if (fieldValue != null && !isBaseType(fieldValue) && field.getModifiers() == Modifier.PRIVATE){
reflectClassWithNewInnerClass(fieldValue,fieldValue.getClass());
}
log.info("fieldName:{},fieldValue:{}",field.getName(),fieldValue);
}
}catch (Exception e){
e.printStackTrace();
}
}
测试方法如下:
private static void testUser7(){
log.info("test 反射获取内部类的私有属性,主类持有内部类属性 start ..");
User7 user7 = new User7();
user7.setName("perry");
//内部类
User7.Role role = user7.new Role();
role.setRoleName("管理员");
user7.setRole(role);
ReflectClass reflectClass = new ReflectClass();
//注意调用对象
reflectClass.reflectClassWithNewInnerClass(user7, User7.class);
log.info("test 反射获取内部类的私有属性,主类持有内部类属性 end ..");
}
至此,关于普通内部类,以及静态内部类反射相关过程已介绍完毕。