Kotlin中@NotNull对Boolean?类型不生效的原因及解决方法
问题原因分析与解决方案
原因解释
- Kotlin的可空类型
Boolean?编译为Java字节码时,会自动添加@Nullable注解,标记该字段允许为null。 - Bean Validation(如Hibernate Validator)执行校验时,会优先识别
@Nullable注解,认为null值是合法的,直接忽略@NotNull的约束。 - 字段的可空类型声明优先级高于注解约束,校验框架会默认遵循类型声明的规则,因此传入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
相关产品推荐
相关产品推荐

