【问题标题】:Kotlin - attribute visibility to companion objectKotlin - 伴随对象的属性可见性
【发布时间】:2017-06-30 05:46:44
【问题描述】:

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

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

我认为伴随对象应该对它们“陪伴”的类的属性具有某种可见性。

我能做些什么来解决这个问题?我怎样才能使MANDATORY_PARAMSMandatoryParametersValidator 及其伴随对象可见?

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

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)
        }
    }
}

非常感谢!

【问题讨论】:

    标签: java kotlin kotlin-interop


    【解决方案1】:

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

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

    2. MANDATORY_PARAMS 的类型从Array&lt;String&gt; 更改为List&lt;String&gt;(因为containsAll 需要Collection。)

    固定的代码如下所示。

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

    【讨论】:

      【解决方案2】:

      MANDATORY_PARAMS 在这种情况下是一个实例属性。 MandatoryParametersValidator 的每个实例都有自己的 MANDATORY_PARAMS 属性,即使它始终是相同的值。

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

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

      class MandatoryParametersValidator {
      
          String[] MANDATORY_PARAMS = ...;
      
          static bool mandatoryParametersHaveBeenProvided(Map<String, String> params) {
              ...
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-23
        相关资源
        最近更新 更多