You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drools中如何将已有对象赋值给新建对象并修改新对象字段值

规则报错与不生效的核心原因

你写的规则存在3个本质问题,既会触发运行异常,也无法实现「原对象不被改动」的要求:

  • Drools规则的when块(LHS)是事实匹配逻辑,不是变量赋值逻辑,你写的$newObject:$customerObject;属于非法的重复变量绑定写法,会直接触发规则解析/运行错误。
  • when块中写$newObject:Customer()是要求工作内存(Working Memory)中必须提前存在另一个独立的Customer事实才能触发规则,既无法自动生成和原对象属性一致的副本,没提前插入对应事实时规则根本不会命中。
  • 你在then块直接修改$customerObject的字段,本质是直接修改插入工作内存的原对象实例;就算你写了$newObject = $customerObject这种Java引用赋值,两个变量也会指向同一块堆内存,修改新变量字段时原对象还是会被改动,完全达不到隔离效果。
正确实现方案

要实现「基于原对象生成独立副本、修改副本不影响原对象、副本传递到后续流程」的需求,遵循两个原则即可:

  1. 所有对象创建、复制操作全部放在then块(RHS)实现,when块只做原事实的条件匹配
  2. 必须生成独立的Customer新实例做属性复制,禁止直接把原对象引用赋值给新变量

可直接运行的规则示例如下:

rule "example"
when
  // 仅匹配符合条件的原Customer对象,不需要在when块声明新对象
  $customerObject : Customer(nameOfBank=="AXIS", salary>=70000)
then
  // 1. 创建独立的Customer新实例
  Customer $newObject = new Customer();
  // 复制原对象所有需要保留的属性到新实例
  $newObject.setNameOfBank($customerObject.getNameOfBank());
  $newObject.setSalary($customerObject.getSalary());
  // 其余需要保留的属性按上述方式逐行复制即可,也可以用BeanUtils、MapStruct这类Bean拷贝工具减少重复代码
  // 如果Customer类实现了Cloneable接口,也可以直接用 Customer $newObject = (Customer) $customerObject.clone(); 快速生成副本,注意默认clone是浅拷贝,存在嵌套引用类型属性时要自行实现深拷贝

  // 2. 仅修改新对象的字段,绝对不要操作$customerObject的字段,避免改动原对象
  $newObject.setIsAligibleforLoan("Yes");
  $newObject.setRateOfInterest(12);
  $newObject.setDocumentNeeded("Yes");

  // 3. 传递新对象到后续流程
  DocumentCheck($newObject);
  // 如果后续其他规则需要用到这个新生成的对象,执行insert($newObject)将其加入工作内存即可
  halt();
end

注意:如果Customer类存在自定义引用类型的成员变量(比如联系方式、地址类属性),一定要做深拷贝,避免新对象和原对象共用嵌套属性的引用,导致修改新对象嵌套字段时意外改动原对象数据。

内容的提问来源于stack exchange,提问作者BeYou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 05:06:18