Kotlin - 将可见性属性赋予伴随对象
Kotlin - attribute visibility to companion object
所以我有下面的代码,是用 Kotlin 编写的。
我在最后一行指令 (return params.keys.containsAll(MANDATORY_PARAMS)
) 遇到编译错误,编译器提示 Unsolved reference: MANDATORY_PARAMS
,但我不太明白为什么。
我认为伴随对象应该对 classes 的属性具有某种可见性,它们 "keep company to"。
我该怎么做才能解决这个问题?我怎样才能使 MANDATORY_PARAMS
对 MandatoryParametersValidator
及其伴生对象都可见?
(免责声明:此代码正在从 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)
}
}
}
非常感谢!
你需要做两件事才能让它工作
将 MANDATORY_PARAMS
移动到伴随对象中。伴随对象就像 Java 中 class 的静态部分。 MANDATORY_PARAMS
在 Java 中将是 static final
。
将 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) {
...
}
}
所以我有下面的代码,是用 Kotlin 编写的。
我在最后一行指令 (return params.keys.containsAll(MANDATORY_PARAMS)
) 遇到编译错误,编译器提示 Unsolved reference: MANDATORY_PARAMS
,但我不太明白为什么。
我认为伴随对象应该对 classes 的属性具有某种可见性,它们 "keep company to"。
我该怎么做才能解决这个问题?我怎样才能使 MANDATORY_PARAMS
对 MandatoryParametersValidator
及其伴生对象都可见?
(免责声明:此代码正在从 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)
}
}
}
非常感谢!
你需要做两件事才能让它工作
将
MANDATORY_PARAMS
移动到伴随对象中。伴随对象就像 Java 中 class 的静态部分。MANDATORY_PARAMS
在 Java 中将是static final
。将
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) {
...
}
}