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

ArchUnit误将Kotlin合成类Phone$WhenMappings判定为违规问题求助

解决ArchUnit检测Kotlin合成类导致的报错问题

我写了一个ArchUnit测试用例,用来校验shared包下只能包含接口、枚举类和数据类。但遇到个问题:当Kotlin代码里用when表达式处理枚举时,编译器会自动生成Phone$WhenMappings这类合成类,ArchUnit会把它当成普通类进行分析,导致测试不符合规则而报错。

解决方案1:排除所有Kotlin合成类

Kotlin生成的合成类通常带有$符号后缀,可以直接通过名称匹配排除这类类:

Java示例

classes().that().resideInAPackage("shared..")
    .and().notHaveNameMatching(".*\\$.*")
    .should().beInterfaces()
    .orShould().beEnums()
    .orShould().beDataClasses();

Kotlin示例

classes()
    .that().resideInAPackage("shared..")
    .and().notHaveNameMatching(".*\\$.*")
    .should { clazz -> 
        clazz.isInterface || clazz.isEnum || clazz.isDataClass 
    }

解决方案2:精准识别并排除合成类

如果担心误排除正常的内部类,可以通过kotlin.Metadata注解的标志位来精准判断是否为Kotlin合成类:

Java示例

classes().that().resideInAPackage("shared..")
    .and().notSatisfy(clazz -> {
        Metadata metadata = clazz.getAnnotation(Metadata.class);
        if (metadata == null) {
            return false;
        }
        // 检查Metadata注解的flags是否包含合成类标识(第21位)
        return (metadata.flags() & (1 << 20)) != 0;
    })
    .should().beInterfaces()
    .orShould().beEnums()
    .orShould().beDataClasses();

解决方案3:针对性排除WhenMappings类

如果只想排除when表达式生成的映射类,可以直接通过名称中的WhenMappings关键词过滤:

classes()
    .that().resideInAPackage("shared..")
    .and().notHaveNameMatching(".*WhenMappings")
    .should { clazz -> 
        clazz.isInterface || clazz.isEnum || clazz.isDataClass 
    }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 04:40:06