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

如何用ArchUnit检测Java类中已初始化的指定类型字段?

用ArchUnit检测已初始化的指定类型字段

给定Java类:

public class A {

   private B b1 = new B();

   private C c = new C();

   private B b2;

}

需求:编写ArchUnit测试,找出类A中类型为B且已完成初始化的字段(即示例中的b1,b2未初始化不会被匹配)。

你提供的未完成测试代码:

@ArchTest
void dontInitialize(JavaClasses classesToTest) {
    noFields().that().haveRawType(DescribedPredicate.describe("that is a B object", type -> {
      return type.isAssignableTo(B.class);
    })).should(new ArchCondition<JavaField>("") {
      @Override
      public void check(JavaField javaField, ConditionEvents conditionEvents) {
        // ???
      }
    });
}

这个需求完全可以实现,ArchUnit提供了直接判断字段初始化状态的API,下面是两种实现方式:

方式一:自定义条件(支持精确匹配初始化方式)

@ArchTest
void findInitializedBFields(JavaClasses classesToTest) {
    fields()
            .that().areDeclaredIn(A.class)
            .and().haveRawType(B.class)
            .should(new ArchCondition<JavaField>("be initialized with a new B instance") {
                @Override
                public void check(JavaField field, ConditionEvents events) {
                    // 先判断字段是否有初始化表达式
                    if (field.getInitializer() != null) {
                        // 可选:严格匹配初始化代码为new B()
                        String initCode = field.getInitializer().getSourceCode();
                        if ("new B()".equals(initCode)) {
                            events.add(SimpleConditionEvent.satisfied(field, field.getName() + " 符合条件:已用new B()初始化"));
                        }
                    } else {
                        events.add(SimpleConditionEvent.violated(field, field.getName() + " 未初始化"));
                    }
                }
            }).check(classesToTest);
}

方式二:使用ArchUnit内置谓词(简洁版)

如果只需要找出所有类型为B且有初始化的字段,不管具体初始化方式,用内置的haveInitializer()谓词更简洁:

@ArchTest
void findInitializedBFieldsSimpler(JavaClasses classesToTest) {
    fields()
            .that().areDeclaredIn(A.class)
            .and().haveRawType(B.class)
            .and().haveInitializer()
            .should().exist() // 断言这类字段存在,也可以替换为其他验证逻辑
            .check(classesToTest);
}

关键说明

  • field.getInitializer():返回字段的初始化表达式对象,非null则表示字段在声明时已完成初始化
  • getInitializer().getSourceCode():可以获取初始化代码的字符串,用于精确匹配初始化方式
  • 内置谓词haveInitializer():直接判断字段是否有初始化表达式,无需自定义条件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:45:06