文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2023-10-24 22:56

关注

目录

目录

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;public class SysUser extends BaseEntity{    private static final long serialVersionUID = 1L;        @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")    private Long userId;        @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;        @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")    private String status;        private String delFlag;        @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;        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 {                //反射的第一种方式        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    }}

来源地址:https://blog.csdn.net/m0_72568404/article/details/131765880

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯