反射全纪录(-)

Java正射,即为通过实例对象访问class对象;Java反射,即是通过class访问对象的属性和方法。

本篇文章,是反射的第一部分,笔者主要分享如下内容:

  • 反射获取本类的私有属性
  • 反射获取父类的私有属性
  • 反射获取本类中非基本类型的私有属性
  • 反射获取泛型类的私有属性
  • 反射获取内部类的私有属性

接下来,我们详细介绍每个部分的内容:


反射获取本类的私有属性

 

用户类User是我们此次研究的主要对象,根据不同的场景,我们将其命名为User1,User2,User3...
根据本次场景,User1是单独的类,相关代码如下:

import lombok.Data;

@Data
public class User1 {
    private Long id;
    private String name;
    private String descr;
}

 


其访问测试方法如下:

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;

@Slf4j
public class ReflectClass {

public void reflectClass(Object object,Class clazz){
    try {
        for (Field field:clazz.getDeclaredFields()){
            //设置可访问属性
            field.setAccessible(true);
            Object fieldValue = field.get(object);
            log.info("fieldName:{},fieldValue:{}",field.getName(),fieldValue);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

}

public static void main(String[] args) {
    User1 user1 = new User1();
    user1.setId(1L);
    user1.setName("perry");
    user1.setDescr("描述");
    ReflectClass reflectClass = new ReflectClass();
    reflectClass.reflectClass(user1, User1.class);
    }
}            

 

在测试方法中,`clazz.getDeclaredFields()` 获取该类的所有声明的属性,包括public,private,protected等等.如果仅仅需要访问private属性,
可以通过`field.getModifiers()`,进行区分,private在该方法下值为2,public为1,protected为4,static为8,final为16,synchronized为32,volatile为64,transient为128。

 

接下来,进入下个专题:

 

反射获取父类的私有属性

 

我们常常会将很多实体类继承一个基类,基类保存相关审计字段,比如createDate,createUser,updateDate,updateUser.

import lombok.Data;
import java.util.Date;

@Data
public class BaseObject {
    private Date createDate;
    private Date updateDate;
    private String createUser;
    private String updateUser;
}

 

User类修改如下,

import lombok.Data;

@Data
public class User2 extends BaseObject{
    private Long id;
    private String name;
    private String descr;
}

 

其实现方法如下:

public void reflectSuperClass(Object object,Class clazz){
    try {
        clazz = clazz.getSuperclass();
        if (clazz != null){
            reflectClass(object,clazz);
          }
        }catch (Exception e){
           e.printStackTrace();
       }
}

 

反射获取本类中非基本类型的私有属性

本次,我们重构下之前的reflectClass()方法,如果其属性不是基本类型,则递归获取其值
本场景下,用户持有Department属性,相实体对象如下:

import lombok.Data;

@Data
public class Department {
    private Long id;
    private Long pid;
    private String name;
    private String descr;
}

 

 

用户类如下:

 

 

import lombok.Data;

@Data
public class User3 {
    private Long id;
    private String name;
    private String descr;

    private Department department;
}

 

 

其实现访问类如下:

public void reflectClass(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)){
                    reflectClass(fieldValue,fieldValue.getClass());
                }
                log.info("fieldName:{},fieldValue:{}",field.getName(),fieldValue);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

private boolean isBaseType(Object object) {
        if (object instanceof String
                || object instanceof Boolean
                || object instanceof Integer
                || object instanceof Double
                || object instanceof Date) {
            return true;
        }
        return false;
    }

 

 


反射获取泛型类的私有属性

实现同 获取本类中非基本类型的私有属性。只不过其用户类定义如下:

import lombok.Data;
@Data
public class User4<T> {
    private Long id;
    private String name;
    private String descr;

    private T data;
}

 

 

测试方法如下:

 

private static void testUser4(){
    log.info("test 反射获取泛型类的私有属性 start ..");
    User4<Department> user4 = new User4<>();
    user4.setName("perry");
    Department department = new Department();
    department.setName("技术部");
    user4.setData(department);
    ReflectClass reflectClass = new ReflectClass();
    reflectClass.reflectClass(user4, User4.class);
    log.info("test 反射获取泛型类的私有属性 end ..");
}

 

 


反射获取内部类的私有属性

 

内部类获取属性的方法,同获取本类中私有属性的方法。只不过测试方式上有区别:
因为内部类存在下列特征:
1. 在内部类中可以随意使用外部类的成员方法以及成员变量。
2.要在外部类中实例化内部类对象的引用。
3.使用this关键字获取内部类与外部类对象的引用。

也就是说,调用的时候,传递的时内部类的对象,而非外部类对象,如果是外部类对象,它就找不到内部类对象了。

该场景下用户类如下声明:

 

import lombok.Data;

@Data
public class User5 {
    private Long id;
    private String name;
    private String descr;

    @Data
    class Role {
    private String roleName;
    }
}

 

 

其测试方法如下:

 

private static void testUser5(){
        log.info("test 反射获取内部类的私有属性 start ..");
        User5 user5 = new User5();
        user5.setName("perry");
        //内部类
        User5.Role role = user5.new Role();
        role.setRoleName("管理员");

        ReflectClass reflectClass = new ReflectClass();
        //注意调用对象
        reflectClass.reflectClassWithInnderClass(role, User5.Role.class);
        log.info("test 反射获取内部类的私有属性 end ..");
    }

 

以上介绍了关于反射的一些场景,以及一些通用的获取属性的方法,相关代码比较详细。
如有需要全部代码,可与我留言。

反射全纪录(-)

上一篇:BZOJ 1969 航线规划 - LCT 维护边双联通分量


下一篇:列表标签