“任何傻瓜都能写出计算机能懂的代码,只有优秀的程序员才能写出人能懂的代码。”
今天,AI 编程工具已经能帮我们生成大量代码,但生成代码的质量却参差不齐。技术债就像慢性病一样,持续消耗团队的战斗力,降低产品质量。如何在 AI 时代保持代码的整洁与可维护?重构这门手艺不仅没有过时,反而变得更加重要。
本文将从 6 个真实的代码坏味道出发,逐一展示从“问题代码”到“优雅代码”的完整重构过程。所有代码示例均可在 Java 17+ 环境中直接运行。
一、代码坏味道:你的代码在“报警”吗?
代码坏味道(Code Smell)是代码中潜在的设计问题的结构性指标。它们不会直接导致程序出错,但会让代码难以理解、难以修改、难以测试。常见的坏味道包括:过长函数、重复代码、深层嵌套条件、上帝类、过长参数列表、过密耦合等。
在开始重构之前,先记住一个核心原则:大胆重构,小心验证。大胆重构是指在 AI 帮助下可以更有信心地进行大规模代码改造;而小心验证则强调,无论 AI 生成的代码多么完美,都必须建立完善的验证机制。
二、6 个重构案例实战
案例一:过长函数 → 提取方法 + 单一职责
坏味道识别:一个方法超过 20 行就应该警惕,超过 50 行基本就是“坏味道”了。过长函数通常混合了多个职责,难以理解和测试。
问题代码:
/**
* 订单处理服务 - 重构前
* 问题:一个方法做了太多事情,超过60行
*/
public class OrderService {
public OrderResult processOrder(Order order, User user) {
// 1. 验证订单参数
if (order == null) {
throw new IllegalArgumentException("订单不能为空");
}
if (order.getItems() == null || order.getItems().isEmpty()) {
throw new IllegalArgumentException("订单商品不能为空");
}
for (OrderItem item : order.getItems()) {
if (item.getProductId() == null) {
throw new IllegalArgumentException("商品ID不能为空");
}
if (item.getQuantity() <= 0) {
throw new IllegalArgumentException("商品数量必须大于0");
}
}
// 2. 计算折扣
double total = 0;
for (OrderItem item : order.getItems()) {
total += item.getPrice() * item.getQuantity();
}
double discount = 0;
if (user.getLevel() == UserLevel.VIP) {
discount = total * 0.15;
} else if (user.getLevel() == UserLevel.GOLD) {
discount = total * 0.10;
} else if (user.getLevel() == UserLevel.SILVER) {
discount = total * 0.05;
}
double finalAmount = total - discount;
// 3. 扣减库存
for (OrderItem item : order.getItems()) {
Product product = productRepository.findById(item.getProductId());
if (product.getStock() < item.getQuantity()) {
throw new RuntimeException("库存不足: " + product.getName());
}
product.setStock(product.getStock() - item.getQuantity());
productRepository.save(product);
}
// 4. 保存订单
order.setTotalAmount(total);
order.setDiscount(discount);
order.setFinalAmount(finalAmount);
order.setStatus(OrderStatus.CREATED);
order.setUserId(user.getId());
Order saved = orderRepository.save(order);
// 5. 发送通知
notificationService.sendOrderCreated(user.getEmail(), saved);
return new OrderResult(saved, finalAmount);
}
}
重构步骤:
- 识别方法中的不同职责(验证、计算、库存、保存、通知)
- 为每个职责提取独立方法
- 确保提取的方法命名清晰、参数合理
重构后代码:
/**
* 订单处理服务 - 重构后
* 每个方法职责单一,可读性和可测试性大幅提升
*/
@Service
@Slf4j
public class OrderService {
private final ProductRepository productRepository;
private final OrderRepository orderRepository;
private final NotificationService notificationService;
public OrderService(ProductRepository productRepository,
OrderRepository orderRepository,
NotificationService notificationService) {
this.productRepository = productRepository;
this.orderRepository = orderRepository;
this.notificationService = notificationService;
}
/**
* 主流程方法 - 现在只有6行,清晰表达了业务流程
*/
public OrderResult processOrder(Order order, User user) {
validateOrder(order);
double total = calculateTotal(order);
double discount = calculateDiscount(total, user.getLevel());
double finalAmount = total - discount;
deductStock(order);
Order saved = saveOrder(order, total, discount, finalAmount, user);
sendNotification(user, saved);
log.info("订单处理成功: orderId={}", saved.getId());
return new OrderResult(saved, finalAmount);
}
/**
* 提取方法1: 参数验证
*/
private void validateOrder(Order order) {
if (order == null) {
throw new IllegalArgumentException("订单不能为空");
}
if (order.getItems() == null || order.getItems().isEmpty()) {
throw new IllegalArgumentException("订单商品不能为空");
}
for (OrderItem item : order.getItems()) {
if (item.getProductId() == null) {
throw new IllegalArgumentException("商品ID不能为空");
}
if (item.getQuantity() <= 0) {
throw new IllegalArgumentException("商品数量必须大于0");
}
}
}
/**
* 提取方法2: 计算总价
*/
private double calculateTotal(Order order) {
return order.getItems().stream()
.mapToDouble(item -> item.getPrice() * item.getQuantity())
.sum();
}
/**
* 提取方法3: 计算折扣 - 使用更清晰的 switch 表达式
*/
private double calculateDiscount(double total, UserLevel level) {
return switch (level) {
case VIP -> total * 0.15;
case GOLD -> total * 0.10;
case SILVER -> total * 0.05;
default -> 0;
};
}
/**
* 提取方法4: 扣减库存
*/
private void deductStock(Order order) {
for (OrderItem item : order.getItems()) {
Product product = productRepository.findById(item.getProductId())
.orElseThrow(() -> new RuntimeException("商品不存在: " + item.getProductId()));
if (product.getStock() < item.getQuantity()) {
throw new RuntimeException("库存不足: " + product.getName());
}
product.setStock(product.getStock() - item.getQuantity());
productRepository.save(product);
}
}
/**
* 提取方法5: 保存订单
*/
private Order saveOrder(Order order, double total, double discount,
double finalAmount, User user) {
order.setTotalAmount(total);
order.setDiscount(discount);
order.setFinalAmount(finalAmount);
order.setStatus(OrderStatus.CREATED);
order.setUserId(user.getId());
return orderRepository.save(order);
}
/**
* 提取方法6: 发送通知
*/
private void sendNotification(User user, Order order) {
notificationService.sendOrderCreated(user.getEmail(), order);
}
}
重构收益:主流程从 60+ 行缩减为 6 行,每个子方法职责单一,单元测试可以独立验证每个逻辑块。
案例二:重复代码 → 提取公共工具 + 模板方法
坏味道识别:相同的代码块出现在多个地方,修改时需要在多处同步变更——这是最容易被忽视的技术债。
问题代码:
// 在多个Service中重复出现类似的日志和异常处理逻辑
@Service
public class UserService {
public User findUser(Long id) {
try {
log.info("开始查询用户, id={}", id);
User user = userRepository.findById(id).orElse(null);
log.info("查询用户完成, id={}, result={}", id, user != null);
return user;
} catch (Exception e) {
log.error("查询用户失败, id={}", id, e);
throw new RuntimeException("查询用户失败", e);
}
}
}
@Service
public class ProductService {
public Product findProduct(Long id) {
try {
log.info("开始查询商品, id={}", id);
Product product = productRepository.findById(id).orElse(null);
log.info("查询商品完成, id={}, result={}", id, product != null);
return product;
} catch (Exception e) {
log.error("查询商品失败, id={}", id, e);
throw new RuntimeException("查询商品失败", e);
}
}
}
重构方案:提取模板方法,使用函数式接口封装可变逻辑。
重构后代码:
/**
* 通用查询模板 - 使用函数式接口封装重复的日志和异常处理
*/
@Component
@Slf4j
public class QueryTemplate {
/**
* 带日志和异常处理的查询模板
* @param operation 具体的查询操作(函数式接口)
* @param entityName 实体名称(用于日志)
* @param id 查询ID
* @return 查询结果
*/
public <T> T executeQuery(Supplier<T> operation, String entityName, Long id) {
try {
log.info("开始查询{}: id={}", entityName, id);
T result = operation.get();
log.info("查询{}完成: id={}, found={}", entityName, id, result != null);
return result;
} catch (Exception e) {
log.error("查询{}失败: id={}", entityName, id, e);
throw new RuntimeException("查询" + entityName + "失败", e);
}
}
/**
* 带重试机制的查询模板(扩展功能)
*/
public <T> T executeQueryWithRetry(Supplier<T> operation, String entityName,
Long id, int maxRetries) {
for (int i = 0; i < maxRetries; i++) {
try {
return executeQuery(operation, entityName, id);
} catch (Exception e) {
if (i == maxRetries - 1) throw e;
log.warn("查询{}重试: id={}, attempt={}", entityName, id, i + 1);
}
}
return null;
}
}
// 重构后的 Service - 代码量减少 70%
@Service
@Slf4j
public class UserService {
private final UserRepository userRepository;
private final QueryTemplate queryTemplate;
public UserService(UserRepository userRepository, QueryTemplate queryTemplate) {
this.userRepository = userRepository;
this.queryTemplate = queryTemplate;
}
public User findUser(Long id) {
return queryTemplate.executeQuery(
() -> userRepository.findById(id).orElse(null),
"用户", id
);
}
}
@Service
@Slf4j
public class ProductService {
private final ProductRepository productRepository;
private final QueryTemplate queryTemplate;
public ProductService(ProductRepository productRepository, QueryTemplate queryTemplate) {
this.productRepository = productRepository;
this.queryTemplate = queryTemplate;
}
public Product findProduct(Long id) {
return queryTemplate.executeQuery(
() -> productRepository.findById(id).orElse(null),
"商品", id
);
}
}
案例三:深层嵌套 if-else → 卫子句 + 策略模式
坏味道识别:超过 3 层的嵌套条件判断会让代码逻辑难以追踪——这就是著名的“箭头代码”。
问题代码:
/**
* 订单处理器 - 重构前
* 问题:深层嵌套if-else,逻辑混乱
*/
public class OrderHandler {
public void handleOrder(Order order) {
if (order != null) {
if (order.getStatus() == OrderStatus.CREATED) {
if (order.getType() == OrderType.NORMAL) {
// 处理普通订单
processNormalOrder(order);
} else {
if (order.getType() == OrderType.PREMIUM) {
// 处理高级订单
processPremiumOrder(order);
} else {
// 处理其他类型
processOtherOrder(order);
}
}
} else if (order.getStatus() == OrderStatus.PAID) {
if (order.getType() == OrderType.NORMAL) {
processPaidNormalOrder(order);
} else {
processPaidPremiumOrder(order);
}
} else {
log.warn("未知订单状态: {}", order.getStatus());
}
} else {
throw new IllegalArgumentException("订单不能为空");
}
}
}
重构步骤:
- 先用卫子句(Guard Clause)处理边界条件
- 再使用策略模式将不同分支逻辑分离
重构后代码:
/**
* 策略接口 - 定义订单处理策略
*/
@FunctionalInterface
public interface OrderStrategy {
void handle(Order order);
}
/**
* 策略工厂 - 根据订单状态和类型获取对应的处理器
*/
@Component
public class OrderStrategyFactory {
private final Map<String, OrderStrategy> strategyMap = new HashMap<>();
public OrderStrategyFactory() {
// 使用Lambda表达式注册各种策略
strategyMap.put(key(OrderStatus.CREATED, OrderType.NORMAL),
this::processNormalOrder);
strategyMap.put(key(OrderStatus.CREATED, OrderType.PREMIUM),
this::processPremiumOrder);
strategyMap.put(key(OrderStatus.PAID, OrderType.NORMAL),
this::processPaidNormalOrder);
strategyMap.put(key(OrderStatus.PAID, OrderType.PREMIUM),
this::processPaidPremiumOrder);
}
private String key(OrderStatus status, OrderType type) {
return status.name() + "_" + type.name();
}
public OrderStrategy getStrategy(Order order) {
String key = key(order.getStatus(), order.getType());
OrderStrategy strategy = strategyMap.get(key);
if (strategy == null) {
throw new IllegalArgumentException("不支持的订单类型: " + key);
}
return strategy;
}
// 具体策略实现
private void processNormalOrder(Order order) {
// 处理普通订单逻辑
log.info("处理普通订单: {}", order.getId());
}
private void processPremiumOrder(Order order) {
// 处理高级订单逻辑
log.info("处理高级订单: {}", order.getId());
}
private void processPaidNormalOrder(Order order) {
// 处理已支付普通订单
log.info("处理已支付普通订单: {}", order.getId());
}
private void processPaidPremiumOrder(Order order) {
// 处理已支付高级订单
log.info("处理已支付高级订单: {}", order.getId());
}
}
// 重构后的 OrderHandler - 使用卫子句 + 策略模式
@Component
@Slf4j
public class OrderHandler {
private final OrderStrategyFactory strategyFactory;
public OrderHandler(OrderStrategyFactory strategyFactory) {
this.strategyFactory = strategyFactory;
}
public void handleOrder(Order order) {
// 卫子句1: 处理null
if (order == null) {
throw new IllegalArgumentException("订单不能为空");
}
// 卫子句2: 处理未知状态
if (order.getStatus() == null || order.getType() == null) {
throw new IllegalArgumentException("订单状态或类型不能为空");
}
// 核心逻辑:一行搞定
strategyFactory.getStrategy(order).handle(order);
}
}
案例四:上帝类 → 拆分为多个协同类
坏味道识别:一个类超过 500 行,承担了多个不相关的职责。这是最严重的坏味道之一,常常导致“改一处坏一片”。
问题代码:
/**
* TransactionManager - 重构前
* 700行的"上帝类",同时处理交易逻辑、数据持久化、通知、界面数据准备、物流
* 参考自真实案例:一个300行的processTransaction方法藏在这个类里
*/
public class TransactionManager {
// 5个不同职责的字段混在一起
private TransactionRepository repo;
private EmailService emailService;
private StockService stockService;
private LogisticsService logistics;
private ViewDataMapper viewMapper;
// 300行的processTransaction方法 - 省略具体实现
public void processTransaction(Transaction transaction) {
// ... 300行代码,混杂了5种不同职责
}
// 还有大量其他方法...
}
重构方案:按照单一职责原则(SRP),将“上帝类”拆分为多个专注的类。
重构后代码:
/**
* 拆分后的5个类,每个只负责一件事
* 参考自真实重构案例
*/
// 1. 只负责核心交易规则
@Service
public class TransactionService {
public TransactionResult process(Order order) {
// 只包含交易核心逻辑
validateOrder(order);
calculateAmount(order);
updateStatus(order);
return new TransactionResult(order);
}
// 约100行
}
// 2. 只负责数据存取
@Repository
public class TransactionRepository {
public void save(Transaction transaction) {
// 只包含数据库操作
}
// 约50行
}
// 3. 只负责发送通知
@Service
public class NotificationService {
public void sendReceipt(User user, Transaction transaction) {
// 只包含通知逻辑
}
// 约80行
}
// 4. 只准备界面需要的数据
@Service
public class TransactionViewModel {
public TransactionDisplayInfo getDisplayInfo(Transaction transaction) {
// 只包含视图数据组装
return new TransactionDisplayInfo(transaction);
}
// 约60行
}
// 5. 只处理物流
@Service
public class LogisticsService {
public String createTrackingNumber() {
// 只包含物流逻辑
return "TN-" + UUID.randomUUID();
}
// 约50行
}
/**
* 协调者 - 原来的TransactionManager变成薄薄的协调层
* 只负责编排,不包含具体业务逻辑
*/
@Component
public class TransactionCoordinator {
private final TransactionService transactionService;
private final TransactionRepository repository;
private final NotificationService notificationService;
private final LogisticsService logisticsService;
public TransactionCoordinator(TransactionService transactionService,
TransactionRepository repository,
NotificationService notificationService,
LogisticsService logisticsService) {
this.transactionService = transactionService;
this.repository = repository;
this.notificationService = notificationService;
this.logisticsService = logisticsService;
}
public void handleTransaction(Order order) {
// 1. 处理交易
TransactionResult result = transactionService.process(order);
// 2. 保存记录
repository.save(result.getTransaction());
// 3. 通知用户
notificationService.sendReceipt(order.getUser(), result.getTransaction());
// 4. 生成物流单(如果是实物商品)
if (order.isPhysicalProduct()) {
logisticsService.createTrackingNumber();
}
}
}
重构收益:每个类从 700 行缩减到 50-100 行,调试时只需看对应的类,单元测试也变得更加简单——测试
TransactionService只需模拟一个Order对象,不再需要模拟整个数据库和邮件系统。
案例五:过长参数列表 → 参数对象封装 + Builder
坏味道识别:方法参数超过 5 个,不仅调用困难,而且参数顺序极易出错。
问题代码:
/**
* 订单创建 - 重构前
* 8个参数,顺序极易搞错,可读性差
*/
public class OrderCreator {
public Order createOrder(Long userId, String userName, String userEmail,
List<OrderItem> items, String shippingAddress,
String paymentMethod, Double discountAmount,
String couponCode) {
// ... 业务逻辑
Order order = new Order();
order.setUserId(userId);
order.setUserName(userName);
order.setUserEmail(userEmail);
order.setItems(items);
order.setShippingAddress(shippingAddress);
order.setPaymentMethod(paymentMethod);
order.setDiscountAmount(discountAmount);
order.setCouponCode(couponCode);
return orderRepository.save(order);
}
}
// 调用方 - 参数顺序容易搞混
Order order = orderCreator.createOrder(123L, "张三", "zhangsan@email.com",
items, "北京市朝阳区...", "支付宝", 10.0, "SUMMER2026");
重构方案:引入 CreateOrderRequest 参数对象 + Builder 模式。
重构后代码:
/**
* 参数对象 - 封装所有创建订单所需的参数
* 使用 Builder 模式,调用方可以清晰传参
*/
@Data
@Builder
public class CreateOrderRequest {
private Long userId;
private String userName;
private String userEmail;
private List<OrderItem> items;
private String shippingAddress;
private String paymentMethod;
private Double discountAmount;
private String couponCode;
// 参数验证逻辑内聚在对象内部
public void validate() {
if (userId == null) {
throw new IllegalArgumentException("用户ID不能为空");
}
if (items == null || items.isEmpty()) {
throw new IllegalArgumentException("订单商品不能为空");
}
// 其他验证...
}
}
// 重构后的 OrderCreator - 参数从8个减少到1个
@Service
public class OrderCreator {
public Order createOrder(CreateOrderRequest request) {
request.validate(); // 验证逻辑内聚
Order order = Order.builder()
.userId(request.getUserId())
.userName(request.getUserName())
.userEmail(request.getUserEmail())
.items(request.getItems())
.shippingAddress(request.getShippingAddress())
.paymentMethod(request.getPaymentMethod())
.discountAmount(request.getDiscountAmount())
.couponCode(request.getCouponCode())
.status(OrderStatus.CREATED)
.build();
return orderRepository.save(order);
}
}
// 调用方 - 清晰易读,不会搞混参数顺序
CreateOrderRequest request = CreateOrderRequest.builder()
.userId(123L)
.userName("张三")
.userEmail("zhangsan@email.com")
.items(items)
.shippingAddress("北京市朝阳区...")
.paymentMethod("支付宝")
.discountAmount(10.0)
.couponCode("SUMMER2026")
.build();
Order order = orderCreator.createOrder(request);
案例六:多链式调用 → 迪米特法则
坏味道识别:a.getB().getC().getD().doSomething() 这种链式调用违反了迪米特法则(最少知识原则),调用方知道太多内部结构,导致耦合过紧。
问题代码:
/**
* 订单报表生成 - 重构前
* 违反迪米特法则:调用方需要知道Order→User→Address的完整路径
*/
@Service
public class OrderReportService {
public String generateReport(Order order) {
// 链式调用暴露了内部结构
String userCity = order.getUser().getAddress().getCity();
String userStreet = order.getUser().getAddress().getStreet();
String userPhone = order.getUser().getPhone();
// 更多链式调用...
String productName = order.getItems().get(0).getProduct().getName();
return String.format("订单报告: 用户%s, 地址%s %s, 电话%s, 商品%s",
order.getUser().getName(), userCity, userStreet, userPhone, productName);
}
}
重构方案:在 Order 类中提供封装方法,隐藏内部导航路径。
重构后代码:
/**
* Order 实体 - 增加封装方法,遵循迪米特法则
*/
@Entity
public class Order {
@ManyToOne
private User user;
@OneToMany
private List<OrderItem> items;
// ... 其他字段
/**
* 封装方法:外部不需要知道 User 内部有 Address
* 遵循迪米特法则 - 只和直接朋友交谈
*/
public String getUserFullAddress() {
if (user == null || user.getAddress() == null) {
return "地址未知";
}
return user.getAddress().getCity() + " " + user.getAddress().getStreet();
}
public String getUserPhone() {
return user != null ? user.getPhone() : "电话未知";
}
public String getUserName() {
return user != null ? user.getName() : "用户未知";
}
public String getFirstProductName() {
if (items == null || items.isEmpty()) {
return "无商品";
}
Product product = items.get(0).getProduct();
return product != null ? product.getName() : "商品未知";
}
}
// 重构后的 OrderReportService - 不再有链式调用
@Service
public class OrderReportService {
public String generateReport(Order order) {
// 直接调用 Order 提供的封装方法
return String.format("订单报告: 用户%s, 地址%s, 电话%s, 商品%s",
order.getUserName(),
order.getUserFullAddress(),
order.getUserPhone(),
order.getFirstProductName()
);
}
}
三、代码坏味道分类脑图

四、AI 辅助重构:2026 年的新工作流
2026 年,AI 已经深度融入重构流程。多项实证研究表明,AI 工具在代码重构方面展现出越来越强的能力。以下是一个结合 Cursor 和 IntelliJ IDEA 2026 AI Agent 的半自动重构工作流。

4.1 各阶段操作指南
阶段1:识别 – 使用 IntelliJ IDEA 的“代码分析”功能或 Cursor 的 Ctrl+I 打开 Composer,输入“扫描当前模块中可能存在的代码坏味道”。Cursor 的项目级上下文理解能够感知整个代码库的结构。
阶段2:规划 – 根据 AI 生成的建议列表,人工评估哪些重构优先级最高。可以参考“技术债热力图”——高频修改的文件优先重构。
阶段3:执行 – 这是 AI 最擅长的环节:
- 提取方法:选中代码段,
Ctrl+K→ “Extract to method” - 拆分大类:在 IDEA 2026.1 中,通过 ACP 协议接入 Cursor 智能体,输入“将 TransactionManager 按职责拆分为多个类”
- 策略模式替换:让 AI 识别条件分支并生成策略类
阶段4:验证 – 运行所有单元测试,AI 可以辅助生成缺失的测试用例。2026 年的实证研究表明,AI 辅助的重构在代码质量提升方面效果显著。
4.2 工具链推荐
| 工具 | 用途 | 2026 年新特性 |
|---|---|---|
| Cursor 3.0 | AI 代码补全与重构 | Agent 调度面板,可同时运行多个 Agent |
| IntelliJ IDEA 2026.1 | IDE + ACP 智能体 | 支持 Codex/Cursor 等任意 AI 智能体 |
| Refrax | 命令行 AI 重构代理 | 专为 Java 代码设计的 AI 重构工具 |
| RefAgent | 多智能体重构框架 | ICSE 2026 研究项目,含规划/执行/测试多 Agent |
五、重构的黄金法则
回顾 6 个案例,可以总结出重构的核心原则:
- 单一职责:每个类/方法只做一件事
- 开闭原则:对扩展开放,对修改关闭
- 迪米特法则:只和直接朋友交谈
- DRY:不要重复自己
- 测试先行:重构前确保有足够的测试覆盖
重构不是一次性工作,而是持续的过程。正如一位开发者在重构完 700 行的“上帝类”后感叹的那样——“调试变得简单了,写单元测试轻松多了”。在 AI 时代,重构的门槛正在降低,但“大胆重构,小心验证”的准则永远不会过时。
系列拓展阅读
- 《Java 开发者上手 Cursor:AI 代码补全与重构实测》 —— AI 辅助重构的实战工具篇
- 《IntelliJ IDEA 2026 AI Agent 深度体验:ACP 协议与 Koog 框架实战》 —— 2026 年 AI 重构工具生态
- 《Java 17 → 21 → 25:生产环境 JDK 升级实战》 —— 利用新 Java 特性重构遗留代码
- 《Arthas 与火焰图:Java 生产环境在线诊断从入门到精通》 —— 重构后的性能诊断工具
参考文献
- Fowler, M. Refactoring: Improving the Design of Existing Code. Addison-Wesley, 1999.
- Azul Systems. “How AI Is Changing Java Refactoring: From Imperative to Functional Code.” 2026. https://www.azul.com/articles/how-ai-is-changing-java-refactoring/
- “Evaluating LLMs-Driven Java Code Refactoring from a Developer’s Perspective.” ICSE 2026.
- “RefAgent: A Multi-agent LLM-based Framework for Automatic Software Refactoring.” ICSE 2026.
- JetBrains. “Code Refactoring in IntelliJ IDEA.” 2026.
- Refrax: Command-Line Agentic Refactoring of Java Code. GitHub.









