Java反射的应用

本文介绍了Java反射机制的基础用法,如获取类的注解、方法和属性,以及如何处理继承类的属性。示例代码展示了如何获取属性名和值,包括私有属性,并提供了实体类转Map、Map转实体类的方法。此外,还讨论了反射在复制对象、打印日志等方面的应用。
摘要由CSDN通过智能技术生成

java 反射最简单的来说就是获取类所包含的注释,方法,属性,值等。我们可以用她来实现复制,转map,通过反射来打印日志等。

我们先创建两个实体类 user继承BaseEntity 类

@Data
public class User extends BaseEntity{
    /**
     * id
     */
    public Integer id;
    /**
     * 姓名
     */
    public String name;
    /**
     * 用户code
     */
    public String userCode;
    /**
     * 用户账号
     */
    public String account;
    /**
     * 用户年龄
     */
    private Integer age;
}
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

/**
 * @author 29027
 */
@Data
public class BaseEntity {
     /**
     * 创建用户
     */
   public Long createUser;
    /**
     * 创建时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    public Date createTime;
    /**
     * 更新时间
     */
    Long updateUser;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    /**
     * 状态
     */
    private Integer status;
    /**
     * 是否删除
     */
    private Integer isDeleted;
    /**
     * 租户
     */
    private String tenantId;
    /**
     * 版本号
     */
    private Long version;
}

创建我们的第一个方法

  /**
     * 获取属性名和属性值
     */
    public static void getsThePropertyNameAndPropertyValue() throws IllegalAccessException {
        User user = new User();
        user.setName("曹操");
        user.setAccount("123456789");
        user.setAge(12);
        /**
         * 这包括公共、受保护、默认(包)访问和私有字段,但不包括继承的字段。
         * */
        Field[] declaredFields1 = new User().getClass().getDeclaredFields();
        for (Field field : declaredFields1) {
            /**
             * 值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。
             * 值为 false 则指示反射的对象应该实施 Java 语言访问检查
             * 简单的来说为true则可以获取私有类的值,提高反射的效率,为false则不能
             * */
            field.setAccessible(true);
            /**
             * field.getName()  返回此 Field 对象所表示的字段的名称
             * 返回指定对象的value值 我指定的user
             * */
            System.out.println(field.getName()+field.get(user));
        }
    }

输出的结果 这样就可以获取到属性名和所对应的value 值

但如果要获取继承的类的怎么办 别着急也有办法

第一种使用 getFields()方法但只能获取到公共方法不能获取到私有方法

   /**
     * 获取属性名和属性值
     */
    public static void  getsThePropertyNameAndPropertyValue2() throws IllegalAccessException {
        User user = new User();
        user.setName("刘备");
        user.setAccount("987654321");
        user.setAge(11);
        user.setIsDeleted(0);
        /**
         * 获取这个类的所有公共方法 包含继承字段 只能获取公共字段 公共字段
         * */
        Field[] fields = User.class.getFields();
        for (Field field : fields) {
            /**
             * field.getName()  返回此 Field 对象所表示的字段的名称
             * 返回指定对象的value值 我指定的user
             * */
            System.out.println(field.getName()+field.get(user));
        }
    }

输出结果

如果要获取私有属性和继承的这么办我们要用另一种方法

  public static void getsThePropertyNameAndPropertyValue3() throws IllegalAccessException {
        User user = new User();
        user.setName("孙权");
        user.setAccount("09871234");
        user.setAge(6);
        user.setIsDeleted(0);
        Integer i = 0;
        Class<?> superclass = user.getClass();
        /**
         * 这包括公共、受保护、默认(包)访问和私有字段,但不包括继承的字段。
         * */
        Field[] declaredFields1 = superclass.getDeclaredFields();
        do {
            System.out.println(declaredFields1.length);
            for (Field field : declaredFields1) {
                field.setAccessible(true);
                /**
                 * field.getName()  返回此 Field 对象所表示的字段的名称
                 * 返回指定对象的value值 我指定的user
                 * */
                System.out.println(field.getName() + field.get(user));
            }
            /**
             * 获取继承类
             * */
            superclass = superclass.getSuperclass();
            /**
             * 这包括公共、受保护、默认(包)访问和私有字段,但不包括继承的字段。
             * */
            declaredFields1 = superclass.getDeclaredFields();
       
            //判断这个是因为所有类都继承了Object的类 Object是所有类的父类 
        } while (!"java.lang.Object".equals(superclass.getName()));
    }

反射获取方法

    /**
     * 返回反射的的所有方法
     */
    public static void method() {
        Method[] declaredMethods = User.class.getDeclaredMethods();
        System.out.println("不包含继承的,包含公共和私有的");
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
        }
        System.out.println("包含继承的,不包含私有的");
        Method[] methods = User.class.getMethods();

        for (Method declaredMethod : methods) {
            System.out.println(declaredMethod.getName());
        }
    }

结果因为文字多 就以文本的形式发

不包含继承的,包含公共和私有的
equals
toString
hashCode
getName
getId
setName
setId
setAccount
getUserCode
setUserCode
setAge
canEqual
getAccount
getAge
包含继承的,不包含私有的
equals
toString
hashCode
getName
getId
setName
setId
setAccount
getUserCode
setUserCode
setAge
getAccount
getAge
setIsDeleted
setTenantId
getStatus
getCreateTime
getCreateUser
setCreateTime
getVersion
getIsDeleted
getUpdateTime
getTenantId
setStatus
setVersion
setUpdateUser
getUpdateUser
setUpdateTime
setCreateUser
wait
wait
wait
getClass
notify
notifyAll

反射还有很多种形式的在次此就不一一举例了 说一下反射常见的应用实体类转map ,map转实体类 ,复制类在此就举这三个例子,当然属于不太完美,只能拷贝公共类,我们可以根据上面的资料进行整个,整个日后有时间会吧他更具完善

 /**
     * 实体类拷贝
     * EntityUtil.copy(user,new NsPrice())
     *
     * @param source 被复制的实体类
     * @param clazz  复制的实体类
     * @return 结果 clazz
     */
    public static <T> T copy(Object source, T clazz) {
        Field[] fields = source.getClass().getFields();
        Field[] fields1 = clazz.getClass().getFields();
        System.out.println(fields1.length);
        for (Field field : fields) {

            for (Field field1 : fields1) {
                //比较类的名称和类型是否一直,如果一直则对类进行赋值
                if (field.getName().equals(field1.getName())
                        && field.getGenericType().equals(field1.getGenericType())) {
                    try {
                        field1.set(clazz, field.get(source));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
       
        }
        return clazz;
    }
  /**
     * 实体对象转成Map
     *
     * @param obj 实体对象
     * @return
     */
    public static Map<String, Object> toMap(Object obj) {
        Map<String, Object> map = new HashMap<>();
        if (obj == null) {
            return map;
        }
        Class clazz = obj.getClass();
        Field[] fields = clazz.getFields();
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(obj));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
 /**
     * Map转成实体对象
     *
     * @param map   实体对象包含属性
     * @param clazz 实体对象类型
     * @return
     */
    public static Object toEntityClass(Map<String, Object> map, Class<?> clazz) {
        if (map == null) {
            return null;
        }
        Object obj = null;
        try {
            obj = clazz.newInstance();

            Field[] fields = obj.getClass().getFields();
            for (Field field : fields) {
                int mod = field.getModifiers();
                if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                    continue;
                }
                field.setAccessible(true);
                field.set(obj, map.get(field.getName()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值