IDEA调试中Evaluate常用操作
文章目录
- IDEA调试中Evaluate常用操作
- 1-IDEA调试中Evaluate常用操作
-
- 一、基础层:数值与变量
-
- [1. 简单计算](#1. 简单计算)
- [2. 修改变量值(改变程序运行轨迹)](#2. 修改变量值(改变程序运行轨迹))
- 二、进阶层:对象操作与方法调用
-
- [3. 调用任意方法(包括私有方法)](#3. 调用任意方法(包括私有方法))
- [4. 创建新对象](#4. 创建新对象)
- [5. 访问/修改私有字段(反射黑科技)](#5. 访问/修改私有字段(反射黑科技))
- [三、集合与 Stream 层](#三、集合与 Stream 层)
-
- [6. 对集合做复杂查询(不用重启程序)](#6. 对集合做复杂查询(不用重启程序))
- [7. 排序、分组、统计](#7. 排序、分组、统计)
- [四、Lambda 与 CompletableFuture 层](#四、Lambda 与 CompletableFuture 层)
-
- [8. 测试 Lambda 表达式](#8. 测试 Lambda 表达式)
- [9. 手动触发异步任务](#9. 手动触发异步任务)
- 五、反射与黑魔法层
-
- [10. 修改静态常量(绕过 final)](#10. 修改静态常量(绕过 final))
- [11. 强制调用私有构造方法](#11. 强制调用私有构造方法)
- [12. 查看线程栈与锁信息](#12. 查看线程栈与锁信息)
- 六、调试专用技巧
-
- [13. 条件断点的"临时版"](#13. 条件断点的"临时版")
- [14. 快速 JSON 序列化看对象内容](#14. 快速 JSON 序列化看对象内容)
- [15. 计算耗时](#15. 计算耗时)
- 七、快捷键与入口
- 八、实战场景速查表
- 九、注意事项

1-IDEA调试中Evaluate常用操作
idea的调试中Evaluate有哪些常用操作?我貌似只能计算int等数值类型的计算,有什么高级用法吗?
IDEA 的 Evaluate Expression(Alt + F8) 是调试中最被低估的神器。它远不止 1 + 1,你可以把它理解成在断点处临时打开一个 REPL 控制台,能执行几乎任何合法的 Java 代码。
下面按从基础到"黑魔法"分层整理:
一、基础层:数值与变量
1. 简单计算
java
// 断点处 Evaluate:
price * 0.85 + 100 // 直接算结果
"ORD-" + orderId // 字符串拼接
items.size() > 0 ? "有货" : "缺货" // 三元表达式
2. 修改变量值(改变程序运行轨迹)
java
// 在断点处,Evaluate 里输入:
stock = 0; // 直接把库存改成0,测试异常分支
user.level = "SVIP"; // 把用户等级改成SVIP,看折扣逻辑
flag = true; // 强制进入某个 if 分支
💡 技巧:不需要写完整语句,直接赋值即可生效,程序会继续用新值执行。
二、进阶层:对象操作与方法调用
3. 调用任意方法(包括私有方法)
java
// 假设当前作用域有 user 对象
user.getName().toUpperCase() // 链式调用
user.validatePassword("123456") // 调用业务方法验证逻辑
calculateDiscount(user, 10000) // 调用当前类的私有方法也行
4. 创建新对象
java
// 在 Evaluate 里直接 new:
new BigDecimal("99.99").multiply(new BigDecimal("1.13"))
new ArrayList<>(items) // 复制集合看内容
new User("U001", "测试用户", "VIP") // 构造假数据测试
5. 访问/修改私有字段(反射黑科技)
java
// 即使字段是 private,Evaluate 也能直接访问:
user.id = "FAKE-ID" // 直接改私有字段
order.status = 99 // 绕过 setter 改状态
三、集合与 Stream 层
6. 对集合做复杂查询(不用重启程序)
java
// 假设 items 是 List<OrderItem>
items.stream()
.filter(i -> i.price > 1000)
.map(i -> i.name)
.collect(Collectors.toList()) // 看哪些商品超过1000元
items.stream()
.mapToDouble(i -> i.price)
.sum() // 快速算总价
7. 排序、分组、统计
java
items.stream()
.sorted(Comparator.comparing(i -> i.price))
.collect(Collectors.toList()) // 看看排序后的结果
items.stream()
.collect(Collectors.groupingBy(i -> i.category)) // 按类别分组
四、Lambda 与 CompletableFuture 层
8. 测试 Lambda 表达式
java
// 在断点处直接试:
Function<Double, Double> discount = p -> p * 0.85;
discount.apply(10000.0) // 测试折扣函数
Predicate<User> isVip = u -> "VIP".equals(u.level);
isVip.test(user) // 测试条件判断
9. 手动触发异步任务
java
// 在调试 CompletableFuture 时,你可以:
CompletableFuture.supplyAsync(() -> fetchPrice())
.thenApply(p -> p * 0.9)
.get() // 在 Evaluate 里手动跑一段异步逻辑看结果
五、反射与黑魔法层
10. 修改静态常量(绕过 final)
java
// 修改静态配置,测试不同场景:
Field field = AppConfig.class.getDeclaredField("MAX_RETRY");
field.setAccessible(true);
field.set(null, 10); // 把最大重试次数改成10
11. 强制调用私有构造方法
java
// 测试单例或私有构造:
Constructor<User> c = User.class.getDeclaredConstructor();
c.setAccessible(true);
User u = c.newInstance(); // 绕过单例限制创建对象
12. 查看线程栈与锁信息
java
Thread.currentThread().getName() // 当前线程名
Thread.currentThread().getStackTrace() // 打印当前调用栈(数组形式)
Thread.holdsLock(someObject) // 是否持有某对象的锁
六、调试专用技巧
13. 条件断点的"临时版"
不想写正式的条件断点?在断点处 Evaluate:
java
// 每次走到这里,Evaluate 输入:
user.id.equals("USER-42") && price > 5000
// 看结果是 true 还是 false,决定是否继续 Step Over
14. 快速 JSON 序列化看对象内容
java
// 如果你项目依赖了 Jackson/Gson:
new ObjectMapper().writeValueAsString(user)
// 直接看到完整的 JSON 格式对象内容,比 Variables 面板清晰多了
15. 计算耗时
java
// 在方法开头和结尾分别 Evaluate:
System.nanoTime() // 记录开始时间
// ... 执行完方法后 ...
System.nanoTime() - start // 算耗时(纳秒)
七、快捷键与入口
| 操作 | 快捷键 | 说明 |
|---|---|---|
| Evaluate Expression | Alt + F8 |
弹出计算窗口 |
| Quick Evaluate | Ctrl + Alt + F8 |
鼠标悬停处快速计算(不弹窗) |
| Evaluate 选中代码 | 选中代码 → 右键 → Evaluate | 只计算选中的部分 |
八、实战场景速查表
| 调试场景 | Evaluate 输入示例 |
|---|---|
| 测试空指针分支 | user = null; |
| 测试库存不足 | stock = 0; |
| 验证正则表达式 | "ORD-2026-001".matches("ORD-\\d{4}-\\d{3}") |
| 看 Map 内容 | map.entrySet().stream().collect(Collectors.toList()) |
| 模拟异常 | throw new RuntimeException("test")(部分版本支持) |
| 查看代理对象真实类 | user.getClass().getName()(看是不是 CGLIB 代理) |
| 计算 MD5 | DigestUtils.md5Hex("password")(有依赖时) |
九、注意事项
- 副作用会真实生效 :Evaluate 里修改的变量、调用的
setter、甚至数据库操作都是真的,不是只读模拟。 - 作用域限制 :只能访问断点处可见的变量和方法(当前类的 private 也可以)。
- 不支持定义新类 :不能写
class Foo {},但可以new Object() { ... }匿名类。 - Stream 操作后原集合不变 :Evaluate 里的 Stream 操作返回新集合,不影响原数据(除非你用
forEach去改)。
下次调试时,试着在断点处按 Alt + F8,输入一段 Stream 或反射代码,你会发现调试效率提升一个量级!