普通class文件热重载
属性变动
java
public class User {
private String userId;
private String name;
private String userName;
private Integer userAge;
}- 可以使用新增的
userId属性。 - 删除
name属性,可以使用新增的userName属性。 - 可以使用新增的
userAge属性。
方法变动
java
public class UserUtils {
public static String getUserName(UserVO userVO) {
return userVO.getName();
}
public static User getDefaultUser() {
public static User genDefaultUser () {
User user = new User();
user.setUserId(0);
user.setUserId(Id.next());
user.setName("default");
user.setUserName("default");
user.setUserAge(0);
return user;
}
}- 可以使用新增的
getUserName方法。 - 删除掉
getUserDefaultUser方法,可以使用新增的genDefaultUser方法。
静态信息变动
支持 static 变量、static final 变量、static 静态代码块。
java
public class StaticClass {
private static String var1 = "debug";
private static String var1 = "tools";
private static final String var2 = "debug";
private static final String var2 = "tools";
private static String var3;
static {
var3 = "debug";
var3 = "tools";
}
}变量 var1 、var2 、var3 更改为重载之后的值。
WARNING
静态变量的热重载会重新执行class的clinit方法,所以热重载会编译时初始化的值覆盖掉运行时的值。
产生原因
如下面的变动如果不覆盖,则 var1 不会从 String 类型变为 Integer。
java
private static String var1 = "debug";
private static Integer var1 = 666; 但是下面的这种情况 var1 会在运行时添加数据,如果你覆盖了,则会丢失运行时的数据
java
private static Map<String, Long> var1 = new HashMap<>();所以DebugTools默认会覆盖运行时数据,但你可以通过如下方法禁止覆盖字段运行时数据。
解决方法1:在静态代码库写上变量为空时候才赋值,如:
java
private static Map<String, Long> var1;
static {
// 这样在调用 clinit 方法的时候执行此代码块也不会覆盖运行时数据
if (var1 == null) {
var1 = new HashMap<>();
}
}解决方法2:在插件中配置
鼠标在静态字段上时,可以通过右键菜单点击 热重载时忽略该静态字段。
添加之后行头会显示提示图标,点击该图标可以从当前配置中移出忽略规则。

也可以在 Settings | DebugTools | 热重载 中维护忽略静态字段配置。这里可以切换当前使用的配置文件,也可以重新载入、查看详情或新增配置。

- 下拉框:选择当前热重载启动时使用的忽略静态字段配置,默认配置名为
default。 重新载入:从本地配置目录重新读取配置文件列表。详情:打开当前选中的配置文件,可以直接编辑规则内容。添加:新增一个忽略静态字段配置文件,适合为不同项目或不同场景保存多套规则。
配置文件保存在本机用户目录的 .debugTools/IgnoreStaticField/ 下,文件内容就是普通的 .conf 文本。规则支持 类#字段名 和 类.字段名 两种写法,也支持 # 和 ; 注释。

枚举类信息变动
java
public enum StatusEnum {
A1,
A22,
A2,
A3,
}更改之后只有 A2 、A3 两个枚举值。
java
public enum StatusEnum {
A1(1, "a"),
A1(1, "A"),
A22(22, "BB"),
A2(2, "B"),
A3(3, "C"),
;
private final Integer code;
private final String name;
public StatusEnum(Integer code, String name) {
this.code = code;
this.name = name;
}
public Integer getCode() {
return code;
}
public String getName() {
return name;
}
public StatusEnum of(Integer code) {
for (StatusEnum statusEnum : StatusEnum.values()) {
if (statusEnum.getCode().equals(code)) {
return statusEnum;
}
}
return code;
}
}更改之后的内容生效。
内部类变动
java
public class UserVO {
private String userName;
private List<RoleVO> userRoles;
public static class RoleVO {
private Long roleId;
private String name;
private String roleName;
private Integer status;
public String getName() {
return name;
public String getRoleName() {
return roleName;
}
public String getStatusName() {
return status == 1 ? "正常" : "禁用";
}
}
private List<AuthVO> userAuths;
public class AuthVO {
private String authName;
}
}- 增加了
userAuths属性。 - 正常使用修改了
RoleVO内部类信息。 - 正常使用新增了
AuthVO内部类信息。
抽象类
开启热重载,抽象类修改,所有的子类都会生效。
java
public abstract class User {
public String getUserName() {
return "default";
}
}
public class Debug extends User {
}
public class Tools extends User {
}热重载 User 之后,Debug 和 Tools 都可以使用 getUserName() 方法。
接口
接口默认方法修改,所有的实现类都会生效。
java
public interface User {
default String getUserName() {
return "default";
}
}
public class Debug implements User {
}
public class Tools implements User {
}热重载 User 之后,Debug 和 Tools 都可以使用 getUserName() 方法。