Kotlin - 将可见性属性赋予伴随对象

Kotlin - attribute visibility to companion object

所以我有下面的代码,是用 Kotlin 编写的。

我在最后一行指令 (return params.keys.containsAll(MANDATORY_PARAMS)) 遇到编译错误,编译器提示 Unsolved reference: MANDATORY_PARAMS,但我不太明白为什么。

我认为伴随对象应该对 classes 的属性具有某种可见性,它们 "keep company to"。

我该怎么做才能解决这个问题?我怎样才能使 MANDATORY_PARAMSMandatoryParametersValidator 及其伴生对象都可见?

(免责声明:此代码正在从 Java 迁移到 Kotlin。在 Java 版本中,mandatoryParametersHaveBeenProvided 曾经是同一个 class 上的静态方法。 )

import javax.validation.ConstraintValidator
import javax.validation.ConstraintValidatorContext

class MandatoryParametersValidator : ConstraintValidator<EnforceMandatoryParameters, Map<String, String>> {

    val MANDATORY_PARAMS = arrayOf("bookingReference", "lastName")

    override fun initialize(constraintAnnotation: EnforceMandatoryParameters?) {
        // do nothing
    }

    override fun isValid(params: Map<String, String>, context: ConstraintValidatorContext?): Boolean {
        MANDATORY_PARAMS
                .filter { !params.containsKey(it) }
                .forEach { parameterName ->
                    context?.disableDefaultConstraintViolation()
                    context?.buildConstraintViolationWithTemplate("Mandatory parameter $parameterName is missing.")?.addConstraintViolation()
                }

        return mandatoryParametersHaveBeenProvided(params)
    }

    companion object {
        fun mandatoryParametersHaveBeenProvided(params: Map<String, String>) : Boolean {
            return params.keys.containsAll(MANDATORY_PARAMS)
        }
    }
}

非常感谢!

你需要做两件事才能让它工作

  1. MANDATORY_PARAMS 移动到伴随对象中。伴随对象就像 Java 中 class 的静态部分。 MANDATORY_PARAMS 在 Java 中将是 static final

  2. MANDATORY_PARAMS 的类型从 Array<String> 更改为 List<String>(因为 containsAll 需要 Collection。)

固定代码如下所示。

    ...

    companion object {
        val MANDATORY_PARAMS = listOf("bookingReference", "lastName")
        fun mandatoryParametersHaveBeenProvided(params: Map<String, String>) : Boolean {
            return params.keys.containsAll(MANDATORY_PARAMS)
        }
    }
}
在这种情况下,

MANDATORY_PARAMS 是一个实例 属性。 MandatoryParametersValidator 的每个实例都将有自己的 MANDATORY_PARAMS 属性,即使它始终是相同的值。

另一方面,伴随对象是单例(就像所有其他 object),并且它们不依赖于 MandatoryParametersValidator 的任何特定实例。因此,要访问 属性,您需要将 class 的实例传递给伴随对象内的函数并读取它具有的 属性,或者将您的 属性 在伴随对象中。

这就像在Java中无法从静态函数访问实例字段和方法一样。您现在拥有的大致相当于此 Java 代码:

class MandatoryParametersValidator {

    String[] MANDATORY_PARAMS = ...;

    static bool mandatoryParametersHaveBeenProvided(Map<String, String> params) {
        ...
    }

}