Java中的反射的作用以及详解

目录

目录

1.反射是什么?

2.反射的优缺点:

3.反射的应用场景:

4.反射创建的三种方式 :

5.反射的常用方法代码示例:

1.实体类(反射获取的类):

2.反射常用方法的示例代码:


1.反射是什么?

Java中的反射是指在运行时动态地获取类的信息以及操作类的成员变量、方法和构造函数的能力。Java反射机制允许程序在运行时获取类的内部信息,包括类的名称、父类、实现的接口、类的字段和方法等,并且可以通过反射机制调用类中的方法和构造函数,访问或修改类中的成员变量。通过反射,可以在运行时动态地创建对象、调用方法、修改变量值等,这样就可以实现一些动态性很强的功能,例如在运行时动态地加载类、动态地调用方法等。反射机制在一些框架和工具库中得到广泛应用,如Spring框架、Hibernate ORM框架等。

2.反射的优缺点:

反射是Java语言的一种特性,它可以让程序在运行时动态地获取类的信息,包括类名、方法名、属性名、构造方法等,并能够通过这些信息创建对象、调用方法和修改属性等。反射的优缺点如下:

优点:

  1. 动态性:反射可以在程序运行时动态地获取类的信息,这使得程序的行为更具有灵活性和可配置性。

  2. 可扩展性:反射可以让程序在运行时动态地加载和调用类,这使得程序可以实现动态扩展和更新功能。

  3. 代码复用:反射可以让程序在运行时动态地调用类的方法和访问属性,这使得程序可以更加方便地重用代码。

  4. 框架与插件机制:反射可以使框架和插件机制更加灵活,它可以让程序在运行时动态地加载和调用类,这样就可以实现动态扩展和更新功能。

缺点:

  1. 性能:反射会带来一定的性能损失,因为反射需要在运行时动态地获取类的信息,并且需要进行类型转换和方法调用等操作,这些都会增加程序的运行时间和内存开销。

  2. 安全性:反射可以让程序访问和修改类的私有属性和方法,这可能会带来安全风险,因为这些操作可能会违反类的封装性和安全性。

  3. 可读性:反射代码通常比普通代码更难理解和维护,因为反射代码需要处理很多细节和异常情况,这可能会影响程序的可读性和可维护性。

总的来说,反射是Java语言中一个非常强大和灵活的特性,它可以让程序在运行时动态地获取类的信息,并且可以实现很多高级的功能。但是反射也有一些缺点,包括性能、安全性和可读性等方面的问题,因此在使用反射时需要权衡利弊,根据具体的业务场景来决定是否使用反射。

3.反射的应用场景:

常见的应用场景:

  1. 框架与插件机制:反射可以使框架和插件机制更加灵活,它可以让程序在运行时动态地加载和调用类,这样就可以实现动态扩展和更新功能。例如,常见的Java框架,如Spring、Hibernate和JUnit等,都使用了反射机制来实现依赖注入、ORM映射和单元测试等功能。

  2. 序列化和反序列化:反射可以在对象序列化和反序列化中使用,序列化是将对象转换为字节流的过程,而反序列化是将字节流转换为对象的过程。通过反射,可以在运行时获取对象的类型信息,并且在序列化和反序列化过程中使用这些信息来生成字节码,从而实现对象的序列化和反序列化。

  3. 动态代理:反射可以实现动态代理,动态代理是一种设计模式,它允许程序在运行时动态地创建一个代理对象,代理对象可以在不改变原始对象的情况下为其提供额外的功能。通过反射,可以动态地创建代理对象,并在代理对象上调用方法,从而实现动态代理的功能。

  4. 单元测试:反射可以在单元测试中使用,它可以让测试代码动态地调用被测试代码中的私有方法和属性,从而实现对代码的全面测试。在JUnit等单元测试框架中,就有很多使用反射机制的测试工具,如ReflectionTestUtils和Whitebox等。

4.反射创建的三种方式 :


        //反射的第一种方式
        SysUser sysUser = new SysUser();
        Class aClass = sysUser.getClass();
        //反射的第二种方式
        Class sysUserClass = SysUser.class;    //获取类模版
        //反射第三种方式
        Class aClass1 = Class.forName("com.ruoyi.common.core.domain.entity.SysUser");

5.反射的常用方法代码示例:

1.实体类(反射获取的类):
package com.ruoyi.common.core.domain.entity;

import java.util.Date;
import java.util.List;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.annotation.Excels;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.xss.Xss;

/**
 * 用户对象 sys_user
 * 
 * @author ruoyi
 */
public class SysUser extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    /** 用户ID */
    @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
    private Long userId;

    /** 部门ID */
    @Excel(name = "部门编号", type = Type.IMPORT)
    private Long deptId;

    /** 用户账号 */
    @Excel(name = "登录名称")
    private String userName;

    /** 用户昵称 */
    @Excel(name = "用户名称")
    private String nickName;

    /** 用户邮箱 */
    @Excel(name = "用户邮箱")
    private String email;

    /** 手机号码 */
    @Excel(name = "手机号码")
    private String phonenumber;

    /** 用户性别 */
    @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
    private String sex;

    /** 用户头像 */
    private String avatar;

    /** 密码 */
    private String password;

    /** 帐号状态(0正常 1停用) */
    @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
    private String status;

    /** 删除标志(0代表存在 2代表删除) */
    private String delFlag;

    /** 最后登录IP */
    @Excel(name = "最后登录IP", type = Type.EXPORT)
    private String loginIp;

    /** 最后登录时间 */
    @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
    private Date loginDate;

    /** 部门对象 */
    @Excels({
        @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
        @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
    })
    private SysDept dept;

    /** 角色对象 */
    private List roles;

    /** 角色组 */
    private Long[] roleIds;

    /** 岗位组 */
    private Long[] postIds;

    /** 角色ID */
    private Long roleId;

    public SysUser()
    {

    }

    public SysUser(Long userId)
    {
        this.userId = userId;
    }

    public Long getUserId()
    {
        return userId;
    }

    public void setUserId(Long userId)
    {
        this.userId = userId;
    }

    public boolean isAdmin()
    {
        return isAdmin(this.userId);
    }

    public static boolean isAdmin(Long userId)
    {
        return userId != null && 1L == userId;
    }

    public Long getDeptId()
    {
        return deptId;
    }

    public void setDeptId(Long deptId)
    {
        this.deptId = deptId;
    }

    @Xss(message = "用户昵称不能包含脚本字符")
    @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
    public String getNickName()
    {
        return nickName;
    }

    public void setNickName(String nickName)
    {
        this.nickName = nickName;
    }

    @Xss(message = "用户账号不能包含脚本字符")
    @NotBlank(message = "用户账号不能为空")
    @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
    public String getUserName()
    {
        return userName;
    }

    public void setUserName(String userName)
    {
        this.userName = userName;
    }

    @Email(message = "邮箱格式不正确")
    @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
    public String getEmail()
    {
        return email;
    }

    public void setEmail(String email)
    {
        this.email = email;
    }

    @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
    public String getPhonenumber()
    {
        return phonenumber;
    }

    public void setPhonenumber(String phonenumber)
    {
        this.phonenumber = phonenumber;
    }

    public String getSex()
    {
        return sex;
    }

    public void setSex(String sex)
    {
        this.sex = sex;
    }

    public String getAvatar()
    {
        return avatar;
    }

    public void setAvatar(String avatar)
    {
        this.avatar = avatar;
    }

    public String getPassword()
    {
        return password;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }

    public String getStatus()
    {
        return status;
    }

    public void setStatus(String status)
    {
        this.status = status;
    }

    public String getDelFlag()
    {
        return delFlag;
    }

    public void setDelFlag(String delFlag)
    {
        this.delFlag = delFlag;
    }

    public String getLoginIp()
    {
        return loginIp;
    }

    public void setLoginIp(String loginIp)
    {
        this.loginIp = loginIp;
    }

    public Date getLoginDate()
    {
        return loginDate;
    }

    public void setLoginDate(Date loginDate)
    {
        this.loginDate = loginDate;
    }

    public SysDept getDept()
    {
        return dept;
    }

    public void setDept(SysDept dept)
    {
        this.dept = dept;
    }

    public List getRoles()
    {
        return roles;
    }

    public void setRoles(List roles)
    {
        this.roles = roles;
    }

    public Long[] getRoleIds()
    {
        return roleIds;
    }

    public void setRoleIds(Long[] roleIds)
    {
        this.roleIds = roleIds;
    }

    public Long[] getPostIds()
    {
        return postIds;
    }

    public void setPostIds(Long[] postIds)
    {
        this.postIds = postIds;
    }

    public Long getRoleId()
    {
        return roleId;
    }

    public void setRoleId(Long roleId)
    {
        this.roleId = roleId;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("userId", getUserId())
            .append("deptId", getDeptId())
            .append("userName", getUserName())
            .append("nickName", getNickName())
            .append("email", getEmail())
            .append("phonenumber", getPhonenumber())
            .append("sex", getSex())
            .append("avatar", getAvatar())
            .append("password", getPassword())
            .append("status", getStatus())
            .append("delFlag", getDelFlag())
            .append("loginIp", getLoginIp())
            .append("loginDate", getLoginDate())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .append("dept", getDept())
            .toString();
    }
}
2.反射常用方法的示例代码:
package com.ruoyi.common.core.domain.entity;

import com.ruoyi.common.annotation.Excel;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class A {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException, NoSuchMethodException {
        /**
         * 反射:
         *     动态获取或者动态调用对象的方法的功能我们称之为java语言的反射机制.
         */

        //反射的第一种方式
        SysUser sysUser = new SysUser();
        Class aClass = sysUser.getClass();
        //反射的第二种方式
        Class sysUserClass = SysUser.class;    //获取类模版
        //反射第三种方式
        Class aClass1 = Class.forName("com.ruoyi.common.core.domain.entity.SysUser");
        //判断这三个是否一样
        System.out.println(aClass == sysUserClass);//true
        System.out.println(aClass == aClass1);//true

        //获取声明式的  例如私有的
        Field userId = aClass.getDeclaredField("userId");
        //暴力反射
        userId.setAccessible(true);
        userId.set(sysUser, 1L);   //这里不能直接写1,因为相对应的实体类是Long类型
        //获取Excel注解
        Excel annotation = userId.getAnnotation(Excel.class);
        System.out.println("annotation.name() = " + annotation.name());//annotation.name() = 用户序号


        //通过获取构造器,获取所有的构造方法
        Constructor[] declaredConstructors = aClass.getDeclaredConstructors();
        //遍历所有的构造方法
        for (Constructor declaredConstructor : declaredConstructors) {
            //获取构造方法的参数的数量是否为0
            if (declaredConstructor.getParameterCount() == 0) {
                System.out.println("declaredConstructor = " + declaredConstructor);
                //实例 通过反射机制实例化了一个aClass的对象,并将它存储在一个Object类型的变量o中。会有 实例化异常:InstantiationException
                Object o = declaredConstructor.newInstance();
                SysUser o1 = (SysUser) o; //强制转换
                //o1 = com.ruoyi.common.core.domain.entity.SysUser@21b8d17c[userId= deptId= userName= nickName= email= phonenumber= sex= avatar= password= status= delFlag= loginIp= loginDate= createBy= createTime= updateBy= updateTime= remark= dept=]
                System.out.println("o1 = " + o1);
            } else {
                Object o = declaredConstructor.newInstance(2222L);
                SysUser o2 = (SysUser) o;
                System.out.println("o2 = " + o2);
            }
        }

        //获取getUserId方法
        Method getUserId = aClass.getDeclaredMethod("getUserId");
        //调用执行
        Object invoke = getUserId.invoke(sysUser);
        System.out.println("invoke = " + invoke); //1
    }
}

你可能感兴趣的:(java基础,java,开发语言)