2016-07-27 23 views
5

Ich versuche, meine Android-App auf Kotlin neu zu schreiben, und ich habe Gesichter Problem beim Konvertieren ContentProvider-Vertragsklasse. So habe ich einfache Vertragsklasse (Standard Sachen wie Inhaltstyp und Inhalt uris weggelassen):Kotlin für Android und statische finale innere Klassen

public final class Contract { 
    public static final class Contacts { 
     public static final String NAME = "Name" 
     public static final String BIRTH = "Birth" 
     public static final String IMAGE = "Image" 
    } 
} 

Wenn ich richtig verstehe, in Kotlin wir haben keine statischen Mitglieder. Stattdessen haben wir "Begleiter Objekte". So, nachdem es zu Kotlin Umwandlung habe ich diesen Code:

object BirthdayContract { 
    class Contacts : BaseColumns { 
     companion object { 
      val NAME = "Name" 
      val BIRTH = "Birth" 
      val IMAGE = "Image" 
     } 
    } 
} 

Aber wenn ich den Zugriff auf Felder wie Contract.Contacts.NAME ich versucht, ich habe Fehler: „NAME hat einen privaten Zugang“. Das Ändern der Sichtbarkeitsmodifikatoren hat keine Auswirkung. Gibt es also eine Möglichkeit, solche Vertragsklassen in Kotlin zu verwenden, oder besser, sie in Java zu behalten?

UPD Ich denke, dass ich klären sollte - mein Anrufer-Code ist auch in Kotlin. Das Problem war in @JvmField Annotation. Damit kann ich direkt auf statische Mitglieder zugreifen, ohne Getter aufzurufen.

+0

Bitte geben Sie einen [MCVE] (http://stackoverflow.com/help/mcve) an. Ich habe deinen 'BirthdayContract' in eine neue Kotlin-Datei eingefügt,' 'BaseColumns' 'entfernt, da er nicht damit kompiliert wird, und eine Funktion erstellt, die' BirthdayContract.Contacts.NAME' aufruft. Ich glaube, dass Sie mehr Informationen und/oder aktualisierte Beispiele bereitstellen müssen, die das Problem, das Sie sehen, zusammenstellen und demonstrieren. Vielen Dank. – mfulton26

+0

@ mfulton26 Ich machte das gleiche - erstellte neue .kt-Datei und kopierte meinen Kotlin-Code hinein. Es kompiliert ohne Fehler. Es gab kein Problem mit der BaseColumns-Schnittstelle. Was für einen Fehler hast du? – noktigula

Antwort

3

NAME ist eine Eigenschaft und standardmäßig hat das Hintergrundfeld einen privaten Zugriff. Aber da es eine Eigenschaft ist, gibt es einen Getter dafür: getNAME().

Da dies nicht, wie Sie natürlich Konstanten in Java zugreifen, gibt es ein paar Möglichkeiten, um direkt das Feld aussetzen:

  1. const: const val NAME = "Name"
  2. @JvmField Anmerkung: @JvmField val NAME = "Name"
+0

@JvmField funktioniert gut für mich, danke! "Const" und "@JvmStatic" beeinflussen jedoch nichts. – noktigula

0

Betrachten mit plain objekt wie folgt:

object Contract { 
    object Contacts { 
     val NAME = "Name" 
     val BIRTH = "Birth" 
     val IMAGE = "Image" 
    } 
} 

Dies sollte perfekt für Ihren ersten Java-Code ausfüllen.

In der neuesten stabilen Kotlin-Version ist public die Standardsichtbarkeit.

Optionially können Sie die const Leitwort für Kompilierung Konstanten hinzufügen, so dass sie in Anmerkungen .: https://kotlinlang.org/docs/reference/properties.html#compile-time-constants

@JvmStatic Anmerkung ist für Java-Interop verwendbar sind, und wenn Sie planen, voll zu gehen Kotlin wirst du nicht brauchen.

0

Sie können es mit einem @JvmStatic

object BirthdayContract { 
    class Contacts : BaseColumns { 
     companion object { 
      @JvmStatic val NAME = "Name" 
      @JvmStatic val BIRTH = "Birth" 
      @JvmStatic val IMAGE = "Image" 
     } 
    } 
} 

//Java 
BirthdayContract.Contacts.Companion.getNAME() 

Bisher habe ich keinen Grund sehen BaseColumns zu verlängern, so dass eine bessere Wahl

object BirthdayContract { 
    object Contacts { 
      const val NAME = "Name" 
      const val BIRTH = "Birth" 
      const val IMAGE = "Image" 

    } 
} 
//Java 
BirthdayContract.Contacts.NAME 

Unterm Strich sein whould ist, dass verschachtelte Objekte in Kotlin nicht sauber aussehen. Bitte beachten Sie Ihren Code vereinfachen

2

Um Konstanten als Feldern aus, mit Anmerkungen versehen sie mit @JvmField

class Contacts { 
    companion object { 
     @JvmField val NAME = "Name" 
     @JvmField val BIRTH = "Birth" 
     @JvmField val IMAGE = "Image" 
    } 
} 

Dann können Sie sie von Java wie folgt verwenden:

String name = Contacts.NAME; 

gesamten Code Einmal ist In Kotlin können Sie die Annotation @JvmField entfernen.