2017-06-30 2 views
1

Also habe ich den Code unten, in Kotlin geschrieben.Kotlin - Attribut Sichtbarkeit auf Companion-Objekt

Ich bekomme einen Kompilierungsfehler auf der letzten Befehlszeile (return params.keys.containsAll(MANDATORY_PARAMS)), der Compiler sagt Unsolved reference: MANDATORY_PARAMS, aber ich verstehe nicht wirklich warum.

Ich dachte, Companion-Objekte sollten eine gewisse Sichtbarkeit in den Attributen der Klassen haben, denen sie "Gesellschaft halten".

Was könnte ich tun, um dies zu lösen? Wie kann ich MANDATORY_PARAMS sowohl für MandatoryParametersValidator als auch für sein Begleitobjekt sichtbar machen?

(Disclaimer:.. Dieser Code von Java Kotlin Auf Java-Version, eine statische Methode auf der gleichen Klasse sein mandatoryParametersHaveBeenProvided verwendet migriert wird)

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

Vielen Dank!

Antwort

3

Sie müssen zwei Dinge tun, um diese Arbeit

  1. Verschieben MANDATORY_PARAMS in den Begleiter-Objekt zu erhalten. Das Begleitobjekt ähnelt den statischen Teilen der Klasse in Java. Und MANDATORY_PARAMS wäre static final in Java.

  2. ändern die Art der MANDATORY_PARAMSArray<String>-List<String> (seit containsAll erfordert eine Collection.)

Der feste Code sieht wie folgt aus.

... 

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

MANDATORY_PARAMS ist eine Instanzeigenschaft in diesem Fall. Jede Instanz von hat ihre eigene MANDATORY_PARAMS Eigenschaft, obwohl sie immer den gleichen Wert hat.

Begleitobjekte dagegen sind Singletons (genau wie alle anderen object), und sie sind nicht an eine bestimmte Instanz von MandatoryParametersValidator gebunden. Um auf diese Eigenschaft zuzugreifen, müssen Sie entweder eine Instanz der Klasse an die Funktion im Companion-Objekt übergeben und die darin enthaltene Eigenschaft lesen oder Ihre Eigenschaft in das Companion-Objekt einfügen.

Dies ist genau so, wie Sie nicht auf Instanzfelder und -methoden von einer statischen Funktion in Java zugreifen können. Was Sie jetzt haben, entspricht ungefähr diesem Java-Code:

class MandatoryParametersValidator { 

    String[] MANDATORY_PARAMS = ...; 

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

}