如何构建ArchUnit规则:查找元注解@Immutable或可赋值于其的类?
解决Archunit查找元注解@Immutable标注类及子类/实现类的问题
错误原因
你之前的代码抛出ClassCastException,是因为simpleNameEndingWith("Immutable")是针对JavaClass的谓词,但CanBeAnnotated.Predicates.metaAnnotatedWith()需要接收匹配JavaAnnotation的谓词。当Archunit尝试将JavaAnnotation实例传入这个谓词时,就会触发类型转换异常。
正确实现代码
要实现你的需求——找到被元注解@Immutable标注的注解所修饰的类,以及继承/实现这类类的子类/实现类,可以按以下步骤编写谓词:
// 1. 定义谓词:匹配被名字以"Immutable"结尾的元注解标注的注解 DescribedPredicate<JavaAnnotation<?>> hasImmutableMetaAnnotation = JavaAnnotation.Predicates.annotatedWith( JavaClass.Predicates.simpleNameEndingWith("Immutable") ); // 2. 定义谓词:匹配被上述注解修饰的类/接口 DescribedPredicate<JavaClass> annotatedWithImmutableMetaAnnotated = JavaClass.Predicates.annotatedWith(hasImmutableMetaAnnotation); // 3. 定义谓词:匹配可赋值给(继承/实现)上述类/接口的类 DescribedPredicate<JavaClass> assignableToImmutableMetaAnnotated = JavaClass.Predicates.assignableTo(annotatedWithImmutableMetaAnnotated); // 4. 合并谓词:满足任一条件即可(若需排除接口,可添加and(JavaClass.Predicates.not(JavaClass.Predicates.isInterface()))) DescribedPredicate<JavaClass> targetClasses = annotatedWithImmutableMetaAnnotated.or(assignableToImmutableMetaAnnotated); // 执行查询并输出 System.out.println(productionClasses.that(targetClasses));
针对示例的调整
如果你的需求是仅返回非接口类(比如示例中的A和B,排除接口C),可以修改最终谓词:
DescribedPredicate<JavaClass> targetClasses = assignableToImmutableMetaAnnotated.or( annotatedWithImmutableMetaAnnotated.and(JavaClass.Predicates.not(JavaClass.Predicates.isInterface())) );
代码说明
- 第一步先定位所有被
@Immutable(或名字以Immutable结尾的元注解)标注的注解,比如示例中的@AnnotationD - 第二步找到被这些注解直接修饰的类/接口,比如示例中的
C - 第三步找到所有继承/实现第二步中类/接口的类,比如示例中的
A和B - 最后合并两个条件,得到你需要的所有目标类
内容的提问来源于stack exchange,提问作者piotrek
相关产品推荐
相关产品推荐

