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