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

Kotlin中@NotNull对Boolean?类型不生效的原因及解决方法

问题原因分析与解决方案

原因解释

  1. Kotlin的可空类型Boolean?编译为Java字节码时,会自动添加@Nullable注解,标记该字段允许为null。
  2. Bean Validation(如Hibernate Validator)执行校验时,会优先识别@Nullable注解,认为null值是合法的,直接忽略@NotNull的约束。
  3. 字段的可空类型声明优先级高于注解约束,校验框架会默认遵循类型声明的规则,因此传入null时不会触发@NotNull校验。

有效校验方案

方案1:改为非空Boolean类型(推荐)

直接将字段类型改为非空的Boolean,既符合Kotlin的类型安全设计,又能让@NotNull注解正常生效。

data class Human(
    @get:NotNull(message = "{err.test}")
    val isCharity: Boolean
)

此时如果请求中isCharity为null或未传入,会立即触发@NotNull的校验提示。

方案2:自定义校验注解(兼容可空类型场景)

如果业务上必须保留Boolean?类型,可以自定义校验注解来强制检查非null:

// 自定义校验注解
@Target(AnnotationTarget.PROPERTY_GETTER)
@Retention(AnnotationRetention.RUNTIME)
@Constraint(validatedBy = [NotNullBooleanValidator::class])
annotation class NotNullBoolean(
    val message: String = "{err.test}",
    val groups: Array<KClass<*>> = [],
    val payload: Array<KClass<out Payload>> = []
)

// 校验器实现
class NotNullBooleanValidator : ConstraintValidator<NotNullBoolean, Boolean?> {
    override fun isValid(value: Boolean?, context: ConstraintValidatorContext): Boolean {
        return value != null
    }
}

// DTO中使用自定义注解
data class Human(
    @get:NotNullBoolean(message = "{err.test}")
    val isCharity: Boolean?
)

方案3:配合Jackson注解强制字段必填

如果需要确保请求中必须携带该字段,可以同时添加Jackson的@JsonProperty(required = true)注解,配合Bean Validation校验:

data class Human(
    @get:NotNull(message = "{err.test}")
    @JsonProperty(required = true)
    val isCharity: Boolean?
)

该注解会让Jackson在解析请求时,如果未找到isCharity字段就抛出异常,后续再由@NotNull校验null值。

内容的提问来源于stack exchange,提问作者A.Sidor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:31:50