目录
目录
1.反射是什么?
Java中的反射是指在运行时动态地获取类的信息以及操作类的成员变量、方法和构造函数的能力。Java反射机制允许程序在运行时获取类的内部信息,包括类的名称、父类、实现的接口、类的字段和方法等,并且可以通过反射机制调用类中的方法和构造函数,访问或修改类中的成员变量。通过反射,可以在运行时动态地创建对象、调用方法、修改变量值等,这样就可以实现一些动态性很强的功能,例如在运行时动态地加载类、动态地调用方法等。反射机制在一些框架和工具库中得到广泛应用,如Spring框架、Hibernate ORM框架等。
2.反射的优缺点:
反射是Java语言的一种特性,它可以让程序在运行时动态地获取类的信息,包括类名、方法名、属性名、构造方法等,并能够通过这些信息创建对象、调用方法和修改属性等。反射的优缺点如下:
优点:
-
动态性:反射可以在程序运行时动态地获取类的信息,这使得程序的行为更具有灵活性和可配置性。
-
可扩展性:反射可以让程序在运行时动态地加载和调用类,这使得程序可以实现动态扩展和更新功能。
-
代码复用:反射可以让程序在运行时动态地调用类的方法和访问属性,这使得程序可以更加方便地重用代码。
-
框架与插件机制:反射可以使框架和插件机制更加灵活,它可以让程序在运行时动态地加载和调用类,这样就可以实现动态扩展和更新功能。
缺点:
-
性能:反射会带来一定的性能损失,因为反射需要在运行时动态地获取类的信息,并且需要进行类型转换和方法调用等操作,这些都会增加程序的运行时间和内存开销。
-
安全性:反射可以让程序访问和修改类的私有属性和方法,这可能会带来安全风险,因为这些操作可能会违反类的封装性和安全性。
-
可读性:反射代码通常比普通代码更难理解和维护,因为反射代码需要处理很多细节和异常情况,这可能会影响程序的可读性和可维护性。
总的来说,反射是Java语言中一个非常强大和灵活的特性,它可以让程序在运行时动态地获取类的信息,并且可以实现很多高级的功能。但是反射也有一些缺点,包括性能、安全性和可读性等方面的问题,因此在使用反射时需要权衡利弊,根据具体的业务场景来决定是否使用反射。
3.反射的应用场景:
常见的应用场景:
-
框架与插件机制:反射可以使框架和插件机制更加灵活,它可以让程序在运行时动态地加载和调用类,这样就可以实现动态扩展和更新功能。例如,常见的Java框架,如Spring、Hibernate和JUnit等,都使用了反射机制来实现依赖注入、ORM映射和单元测试等功能。
-
序列化和反序列化:反射可以在对象序列化和反序列化中使用,序列化是将对象转换为字节流的过程,而反序列化是将字节流转换为对象的过程。通过反射,可以在运行时获取对象的类型信息,并且在序列化和反序列化过程中使用这些信息来生成字节码,从而实现对象的序列化和反序列化。
-
动态代理:反射可以实现动态代理,动态代理是一种设计模式,它允许程序在运行时动态地创建一个代理对象,代理对象可以在不改变原始对象的情况下为其提供额外的功能。通过反射,可以动态地创建代理对象,并在代理对象上调用方法,从而实现动态代理的功能。
-
单元测试:反射可以在单元测试中使用,它可以让测试代码动态地调用被测试代码中的私有方法和属性,从而实现对代码的全面测试。在JUnit等单元测试框架中,就有很多使用反射机制的测试工具,如ReflectionTestUtils和Whitebox等。
4.反射创建的三种方式 :
//反射的第一种方式 SysUser sysUser = new SysUser(); Class extends SysUser> 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 extends SysUser> 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