Was entspricht statischen Java-Methoden in Kotlin?


619

Es gibt kein staticSchlüsselwort in Kotlin.

Wie lässt sich eine staticJava-Methode in Kotlin am besten darstellen ?


8
Verwenden Sie eine Funktion auf Paketebene .
Phoenix

12
Beachten Sie: Kotlin hat Statiken im Java-Stil entfernt, um wartungsfähigere (ich wage es zu sagen "bessere") Codierungspraktiken zu fördern. Statische Globale sind im Allgemeinen gegen das OOP-Paradigma, können aber sehr praktisch sein. Daher hat Kotlin uns Gefährten zur Verfügung gestellt, eine OOP-freundlichere Art, Statik zu haben.
Nicholas Miller

Laut Google ist Kotlin jetzt die bevorzugte Sprache für die Android-Entwicklung.
AFD

@NicholasMiller warum ist es OOP-freundlicher? Ich denke, es ist einfacher zu lesen und zu schreiben, ohne den wiederkehrenden Hinweis auf statische Aufladung (Boilerplate). Oder gibt es noch einen guten Grund?
Torben G

Antworten:


888

Sie platzieren die Funktion im "Begleitobjekt".

Also der Java-Code wie folgt:

class Foo {
  public static int a() { return 1; }
}

wird werden

class Foo {
  companion object {
     fun a() : Int = 1
  }
}

Sie können es dann aus dem Kotlin-Code als verwenden

Foo.a();

Aber innerhalb von Java-Code müssten Sie es als aufrufen

Foo.Companion.a();

(Was auch innerhalb von Kotlin funktioniert.)

Wenn Sie das CompanionBit nicht angeben müssen , können Sie entweder eine @JvmStaticAnmerkung hinzufügen oder Ihre Begleitklasse benennen.

Aus den Dokumenten :

Begleitobjekte

Eine Objektdeklaration innerhalb einer Klasse kann mit dem Schlüsselwort Companion gekennzeichnet werden:

class MyClass {
   companion object Factory {
       fun create(): MyClass = MyClass()
   }
}

Mitglieder des Begleitobjekts können aufgerufen werden, indem einfach der Klassenname als Qualifikationsmerkmal verwendet wird:

val instance = MyClass.create()

...

In der JVM können jedoch Mitglieder von Begleitobjekten als echte statische Methoden und Felder generiert werden, wenn Sie die @JvmStatic Anmerkung verwenden. Weitere Informationen finden Sie im Abschnitt zur Java-Interoperabilität.

Das Hinzufügen der @JvmStaticAnmerkung sieht folgendermaßen aus

class Foo {
  companion object {
    @JvmStatic
    fun a() : Int = 1;
  }
}

und dann wird es als echte statische Java-Funktion existieren, auf die sowohl von Java als auch von Kotlin als zugegriffen werden kann Foo.a().

Wenn der CompanionName nur nicht gefällt, können Sie auch einen expliziten Namen für das Begleitobjekt angeben, der folgendermaßen aussieht:

class Foo {
  companion object Blah {
    fun a() : Int = 1;
  }
}

Damit können Sie es von Kotlin auf die gleiche Weise aufrufen, aber von Java-ähnlich Foo.Blah.a()(was auch in Kotlin funktioniert).


4
In Kotlin wird es sein fun a(): Int { return 1 }oder sogarfun a(): Int = 1
Dmitry Zaytsev

3
@DmitryZaitsev oder sogar fun a() = 1.
Moira

Was bedeutet Fabrik?
Bagus Aji Santoso

@BagusAjiSantoso Factoryist der Name des Begleitobjekts - aber wofür kann das verwendet werden? Ich habe keine Ahnung, aber ich war interessiert, also habe ich eine Frage dazu erstellt: stackoverflow.com/q/45853459/221955 .
Michael Anderson

1
@ Yajairo87 Ich denke, was Sie fragen, ist zu viel, um es in einem Kommentar hier zu behandeln - also habe ich eine Frage erstellt, die sich direkt damit befasst: stackoverflow.com/questions/47046474/…
Michael Anderson

154

Docs empfiehlt für statische Funktionen mit dem meisten Bedürfnissen zu lösen Funktionen auf Paketebene . Sie werden einfach außerhalb einer Klasse in einer Quellcodedatei deklariert. Das Paket einer Datei kann am Anfang einer Datei mit dem Schlüsselwort package angegeben werden.

Erklärung

package foo

fun bar() = {}

Verwendungszweck

import foo.bar

Alternative

import foo.*

Sie können die Funktion jetzt aufrufen mit:

bar()

oder wenn Sie das Schlüsselwort import nicht verwenden:

foo.bar()

Wenn Sie das Paket nicht angeben, kann auf die Funktion über das Stammverzeichnis zugegriffen werden.

Wenn Sie nur Erfahrung mit Java haben, scheint dies ein wenig seltsam. Der Grund ist, dass Kotlin keine streng objektorientierte Sprache ist. Man könnte sagen, es unterstützt Methoden außerhalb von Klassen.

Bearbeiten: Sie haben die Dokumentation so bearbeitet, dass sie den Satz über die Empfehlung von Funktionen auf Paketebene nicht mehr enthält. Dies ist das Original, auf das oben Bezug genommen wurde.


8
Beachten Sie, dass diese "Top-Level" - oder "Package" -Funktionen unter der Haube tatsächlich in ihre eigene Klasse kompiliert werden. Im obigen Beispiel würde der Compiler eine class FooPackagemit allen Eigenschaften und Funktionen der obersten Ebene erstellen und alle Ihre Verweise entsprechend an diese weiterleiten. Weitere Infos von Jetbrains.
Mitchell Tracy

29
+1 Zur Erklärung, wie man das Äquivalent in Kotlin richtig macht und nicht nur das Spiegeläquivalent aus Java.
Phoenix

1
Dies sollte die akzeptierte Antwort sein oder ein Mod sollte die akzeptierte Antwort aktualisieren, um Funktionen auf
Paketebene

@MitchellTracy Ausgezeichnete Informationen! Vielen Dank.
Ein Droide

1
Dies ist die bisher bessere Lösung. Ich wollte nur klarstellen, dass, wo Sie die Funktion definieren bar(), der Dateiname keine Rolle spielt, Sie sie benennen können BarUtils.ktoder was auch immer, dann, wie der Text sagt, werden Sie sie mit importierenimport <package name>.bar
Mariano Ruiz

33

A. Alter Java-Weg:

  1. Deklarieren Sie a companion object, um eine statische Methode / Variable einzuschließen

    class Foo{
    companion object {
        fun foo() = println("Foo")
        val bar ="bar"  
        }
    }
  2. Verwenden :

    Foo.foo()        // Outputs Foo    
    println(Foo.bar) // Outputs bar


B. Neuer Kotlin-Weg

  1. Deklarieren Sie direkt in einer Datei ohne Klasse in einer .ktDatei.

    fun foo() = println("Foo")
    val bar ="bar"
  2. Verwenden Sie die methods/variablesmit ihren Namen . ( Nach dem Import )

    Verwenden :

    foo()        // Outputs Foo          
    println(bar) // Outputs bar     


Wenn ich versuche, in einer anderen Klasse zu initialisieren, gibt es java.lang.ExceptionInInitializerError und ich verwende var anstelle von val
Sudarshan

4
Methodenaufrufe müssen das INSTANCESchlüsselwort haben, wie Foo.INSTANCE.sayFoo()
folgt

Ich denke, diese Lösung ist der bevorzugte Weg, wenn Sie eine static CLASSnicht nur wollen static methdos. Denn mit Begleitobjekten können Sie die übergeordnete Klasse weiterhin instanziieren.
Fabriciorissetto

valist nicht statisch, es entspricht static finalJava
Farid

23

Verwenden Sie object , um val / var / method darzustellen und statisch zu machen. Sie können auch ein Objekt anstelle einer Singleton-Klasse verwenden. Sie können Companion verwenden, wenn Sie innerhalb einer Klasse statisch machen möchten

object Abc{
     fun sum(a: Int, b: Int): Int = a + b
    }

Wenn Sie es von Java aus aufrufen müssen:

int z = Abc.INSTANCE.sum(x,y);

Ignorieren Sie in Kotlin INSTANCE.


11

Das hat auch bei mir funktioniert

object Bell {
    @JvmStatic
    fun ring() { }
}

von Kotlin

Bell.ring()

von Java

Bell.ring()

8
object objectName {
    fun funName() {

    }
}

5
Während dieses Code-Snippet die Lösung sein kann, hilft das Hinzufügen einer Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Narendra Jadhav

5

Sie müssen das Begleitobjekt für die statische Methode übergeben, da kotlin kein statisches Schlüsselwort hat. Mitglieder des Begleitobjekts können aufgerufen werden, indem einfach der Klassenname als Qualifikationsmerkmal verwendet wird:

package xxx
    class ClassName {
              companion object {
                       fun helloWord(str: String): String {
                            return stringValue
                      }
              }
    }

4

Es gibt zwei Möglichkeiten, wie Sie statisch in Kotlin anwenden können

Erstellen Sie zuerst ein Begleitobjekt unter Klasse

Zum Beispiel:

class Test{
    companion object{
          fun isCheck(a:Int):Boolean{
             if(a==0) true else false
          }
     }
}

Sie können diese Funktion als aufrufen

Test.Companion.isCheck(2)

Eine andere Möglichkeit besteht darin, eine Objektklasse zu erstellen

object Test{
       fun isCheck(a:Int):Boolean{
            if(a==0) true else false
       }
}

Viel Spaß beim Codieren!


Bei der ersten Verwendung (dh Test.Companion.isCheck(2)) zeigt IDE Warnungen an und sagt Companion reference is redundant. Es kann auf reduziert werden Test.isCheck(2)und die reduzierte Form kommt dem Java-Äquivalent näher.
VSB

3

Kotlin hat kein statisches Schlüsselwort. Du hast das für Java benutzt

 class AppHelper {
        public static int getAge() {
            return 30;
        }
    }

und für Kotlin

class AppHelper {
        companion object {
            fun getAge() : Int = 30
        }
    }

Rufen Sie nach Java

AppHelper.getAge();

Rufen Sie nach Kotlin

AppHelper.Companion.getAge();

Ich denke, es funktioniert perfekt.


3

Ich möchte den obigen Antworten etwas hinzufügen.

Ja, Sie können Funktionen in Quellcodedateien (außerhalb der Klasse) definieren. Es ist jedoch besser, wenn Sie statische Funktionen innerhalb der Klasse mit Companion Object definieren, da Sie durch Nutzung der Kotlin-Erweiterungen weitere statische Funktionen hinzufügen können .

class MyClass {
    companion object { 
        //define static functions here
    } 
}

//Adding new static function
fun MyClass.Companion.newStaticFunction() {
    // ...
}

Sie können die oben definierte Funktion aufrufen, da Sie jede Funktion in Companion Object aufrufen.


3

Obwohl dies jetzt etwas mehr als 2 Jahre alt ist und viele gute Antworten hatte, sehe ich, dass einige andere Möglichkeiten, "statische" Kotlin-Felder zu erhalten, fehlen. Hier ist eine Beispielanleitung für Kotlin-Java staticInterop:

Szenario 1: Erstellen einer statischen Methode in Kotlin für Java

Kotlin

@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java
package com.frybits

class KotlinClass {
    companion object {

        //This annotation tells Java classes to treat this method as if it was a static to [KotlinClass]
        @JvmStatic
        fun foo(): Int = 1

        //Without it, you would have to use [KotlinClass.Companion.bar()] to use this method.
        fun bar(): Int = 2
    }
}

Java

package com.frybits;

class JavaClass {

    void someFunction() {
        println(KotlinClass.foo()); //Prints "1"
        println(KotlinClass.Companion.bar()); //Prints "2". This is the only way to use [bar()] in Java.
        println(KotlinClass.Companion.foo()); //To show that [Companion] is still the holder of the function [foo()]
    }

    //Because I'm way to lazy to keep typing [System.out], but I still want this to be compilable.
    void println(Object o) {
        System.out.println(o);
    }
}

Michael Andersons Antwort bietet mehr Tiefe als diese und sollte für dieses Szenario definitiv referenziert werden.


In diesem nächsten Szenario werden statische Felder in Kotlin erstellt, damit Java nicht ständig KotlinClass.foo()nach Fällen aufrufen muss, in denen Sie keine statische Funktion wünschen.

Szenario 2: Erstellen einer statischen Variablen in Kotlin für Java

Kotlin

@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java
package com.frybits

class KotlinClass {

    companion object {

        //This annotation tells Kotlin to not generate the getter/setter functions in Java. Instead, this variable should be accessed directly
        //Also, this is similar to [@JvmStatic], in which it tells Java to treat this as a static variable to [KotlinClass].
        @JvmField
        var foo: Int = 1

        //If you want something akin to [final static], and the value is a primitive or a String, you can use the keyword [const] instead
        //No annotation is needed to make this a field of [KotlinClass]. If the declaration is a non-primitive/non-String, use @JvmField instead
        const val dog: Int = 1

        //This will be treated as a member of the [Companion] object only. It generates the getter/setters for it.
        var bar: Int = 2

        //We can still use [@JvmStatic] for 'var' variables, but it generates getter/setters as functions of KotlinClass
        //If we use 'val' instead, it only generates a getter function
        @JvmStatic
        var cat: Int = 9
    }
}

Java

package com.frybits;

class JavaClass {

    void someFunction() {
        //Example using @JvmField
        println(KotlinClass.foo); //Prints "1"
        KotlinClass.foo = 3;

        //Example using 'const val'
        println(KotlinClass.dog); //Prints "1". Notice the lack of a getter function

        //Example of not using either @JvmField, @JvmStatic, or 'const val'
        println(KotlinClass.Companion.getBar()); //Prints "2"
        KotlinClass.Companion.setBar(3); //The setter for [bar]

        //Example of using @JvmStatic instead of @JvmField
        println(KotlinClass.getCat());
        KotlinClass.setCat(0);
    }

    void println(Object o) {
        System.out.println(o);
    }
}

Eine der großartigen Funktionen von Kotlin ist, dass Sie Funktionen und Variablen der obersten Ebene erstellen können. Dies macht es großartig, "klassenlose" Listen konstanter Felder und Funktionen zu erstellen, die wiederum als staticFunktionen / Felder in Java verwendet werden können.

Szenario 3: Zugriff auf Felder und Funktionen der obersten Ebene in Kotlin von Java aus

Kotlin

//In this example, the file name is "KSample.kt". If this annotation wasn't provided, all functions and fields would have to accessed
//using the name [KSampleKt.foo()] to utilize them in Java. Make life easier for yourself, and name this something more simple
@file:JvmName("KotlinUtils")

package com.frybits

//This can be called from Java as [KotlinUtils.TAG]. This is a final static variable
const val TAG = "You're it!"

//Since this is a top level variable and not part of a companion object, there's no need to annotate this as "static" to access in Java.
//However, this can only be utilized using getter/setter functions
var foo = 1

//This lets us use direct access now
@JvmField
var bar = 2

//Since this is calculated at runtime, it can't be a constant, but it is still a final static variable. Can't use "const" here.
val GENERATED_VAL:Long = "123".toLong()

//Again, no need for @JvmStatic, since this is not part of a companion object
fun doSomethingAwesome() {
    println("Everything is awesome!")
}

Java

package com.frybits;

class JavaClass {

    void someFunction() {

        println(KotlinUtils.TAG); //Example of printing [TAG]


        //Example of not using @JvmField.
        println(KotlinUtils.getFoo()); //Prints "1"
        KotlinUtils.setFoo(3);

        //Example using @JvmField
        println(KotlinUtils.bar); //Prints "2". Notice the lack of a getter function
        KotlinUtils.bar = 3;

        //Since this is a top level variable, no need for annotations to use this
        //But it looks awkward without the @JvmField
        println(KotlinUtils.getGENERATED_VAL());

        //This is how accessing a top level function looks like
        KotlinUtils.doSomethingAwesome();
    }

    void println(Object o) {
        System.out.println(o);
    }
}

Eine weitere bemerkenswerte Erwähnung, die in Java als "statische" Felder verwendet werden kann, sind Kotlin- objectKlassen. Dies sind Nullparameter-Singleton-Klassen, die bei der ersten Verwendung träge instanziiert werden. Weitere Informationen dazu finden Sie hier: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations

Für den Zugriff auf den Singleton wird jedoch ein spezielles INSTANCEObjekt erstellt, dessen Handhabung genauso umständlich Companionist wie es ist. So verwenden Sie Anmerkungen, um staticJava ein sauberes Gefühl zu verleihen :

Szenario 4: Verwenden von objectKlassen

Kotlin

@file:JvmName("KotlinClass")

//This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java
package com.frybits

object KotlinClass { //No need for the 'class' keyword here.

    //Direct access to this variable
    const val foo: Int = 1

    //Tells Java this can be accessed directly from [KotlinClass]
    @JvmStatic
    var cat: Int = 9

    //Just a function that returns the class name
    @JvmStatic
    fun getCustomClassName(): String = this::class.java.simpleName + "boo!"

    //Getter/Setter access to this variable, but isn't accessible directly from [KotlinClass]
    var bar: Int = 2

    fun someOtherFunction() = "What is 'INSTANCE'?"
}

Java

package com.frybits;

class JavaClass {

    void someFunction() {
        println(KotlinClass.foo); //Direct read of [foo] in [KotlinClass] singleton

        println(KotlinClass.getCat()); //Getter of [cat]
        KotlinClass.setCat(0); //Setter of [cat]

        println(KotlinClass.getCustomClassName()); //Example of using a function of this 'object' class

        println(KotlinClass.INSTANCE.getBar()); //This is what the singleton would look like without using annotations
        KotlinClass.INSTANCE.setBar(23);

        println(KotlinClass.INSTANCE.someOtherFunction()); //Accessing a function in the object class without using annotations
    }

    void println(Object o) {
        System.out.println(o);
    }
}

3

Um es kurz zu machen, könnten Sie "Companion Object" verwenden , um in die statische Welt von Kotlin zu gelangen, wie:

  companion object {
    const val TAG = "tHomeFragment"
    fun newInstance() = HomeFragment()
}

und um ein konstantes Feld zu erstellen, verwenden Sie "const val" wie im Code. Vermeiden Sie jedoch die statischen Klassen, da dies beim Testen von Einheiten mit Mockito! zu Schwierigkeiten führt.


3

Die genaue Konvertierung der statischen Java-Methode in ein Kotlin-Äquivalent wäre wie folgt. zB Hier hat die util-Klasse eine statische Methode, die sowohl in Java als auch in Kotlin gleichwertig wäre. Die Verwendung von @JvmStatic ist wichtig.

Java-Code:

    class Util{
         public static String capitalize(String text){
         return text.toUpperCase();}
       }

Kotlin-Code:

    class Util {
        companion object {
            @JvmStatic
            fun capitalize(text:String): String {
                return text.toUpperCase()
            }
        }
    }

2

Sie müssen lediglich ein Begleitobjekt erstellen und die Funktion darin einfügen

  class UtilClass {
        companion object {
  //        @JvmStatic
            fun repeatIt5Times(str: String): String = str.repeat(5)
        }
    }

So rufen Sie die Methode aus einer Kotlin-Klasse auf:

class KotlinClass{
  fun main(args : Array<String>) { 
    UtilClass.repeatIt5Times("Hello")
  }
}

oder Import verwenden

import Packagename.UtilClass.Companion.repeatIt5Times
class KotlinClass{
  fun main(args : Array<String>) { 
     repeatIt5Times("Hello")
  }
}

So rufen Sie die Methode von einer Java-Klasse aus auf:

 class JavaClass{
    public static void main(String [] args){
       UtilClass.Companion.repeatIt5Times("Hello");
    }
 }

oder indem Sie der Methode die Annotation @JvmStatic hinzufügen

class JavaClass{
   public static void main(String [] args){
     UtilClass.repeatIt5Times("Hello")
   }
}

oder beides, indem Sie der Methode eine @ JvmStatic-Annotation hinzufügen und einen statischen Import in Java durchführen

import static Packagename.UtilClass.repeatIt5Times
class JavaClass{
   public static void main(String [] args){
     repeatIt5Times("Hello")
   }
}

2

Für Java:

public class Constants {
public static final long MAX_CLICK_INTERVAL = 1000;}

Äquivalenter Kotlin-Code:

object  Constants {
const val MAX_CLICK_INTERVAL: Long = 1000}

Das Äquivalent zu statischen Java-Methoden ist also die Objektklasse in Kotlin.


2

Für Android wird eine Zeichenfolge von einer einzelnen Aktivität bis zu allen erforderlichen Aktivitäten verwendet. Genau wie statisch in Java

public final static String TEA_NAME = "TEA_NAME";

Gleichwertiger Ansatz in Kotlin:

class MainActivity : AppCompatActivity() {
    companion object {
        const val TEA_NAME = "TEA_NAME"
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

Eine weitere Aktivität, bei der Wert benötigt wird:

val teaName = MainActivity.TEA_NAME

2

Mit Ausnahme von Michael Andersons Antwort habe ich in meinem Projekt Codierung mit anderen zwei Möglichkeiten.

Zuerst:

Sie können alle Variablen einer Klasse zuordnen. hat eine Kotlin-Datei namens Const erstellt

object Const {
    const val FIRST_NAME_1 = "just"
    const val LAST_NAME_1 = "YuMu"
}

Sie können es in Kotlin- und Java-Code verwenden

 Log.d("stackoverflow", Const.FIRST_NAME_1)

Zweite:

Sie können die Erweiterungsfunktion von Kotlin verwenden, mit der
eine Kotlin-Datei mit dem Namen Ext erstellt wurde. Unter Code ist der gesamte Code in der Ext-Datei

package pro.just.yumu

/**
 * Created by lpf on 2020-03-18.
 */

const val FIRST_NAME = "just"
const val LAST_NAME = "YuMu"

Sie können es in Kotlin-Code verwenden

 Log.d("stackoverflow", FIRST_NAME)

Sie können es in Java-Code verwenden

 Log.d("stackoverflow", ExtKt.FIRST_NAME);

1

Schreiben Sie sie direkt in Dateien.

In Java (hässlich):

package xxx;
class XxxUtils {
  public static final Yyy xxx(Xxx xxx) { return xxx.xxx(); }
}

In Kotlin:

@file:JvmName("XxxUtils")
package xxx
fun xxx(xxx: Xxx): Yyy = xxx.xxx()

Diese beiden Codeteile werden nach der Kompilierung gleichgestellt (selbst der kompilierte Dateiname file:JvmNamewird verwendet, um den kompilierten Dateinamen zu steuern, der unmittelbar vor der Deklaration des Paketnamens stehen sollte).


7
Sie haben "Kotlin (hässlich)" vergessen ... KOTLIN: Begleitobjekt {val handler = Objekt: Handler (Looper.getMainLooper ()) {] ..... JAVA: statischer Handler handler = neuer Handler (Looper.getMainLooper () ) {};
CmosBattery

1

Verwenden Sie @JVMStaticAnnotation

companion object {

    // TODO: Rename and change types and number of parameters
    @JvmStatic
    fun newInstance(param1: String, param2: String) =
            EditProfileFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
}

1

Lassen Sie, Sie haben eine Klasse Student . Und Sie haben eine statische Methode getUniversityName () und ein statisches Feld namens totalStudent .

Sie sollten den Begleitobjektblock in Ihrer Klasse deklarieren .

companion object {
 // define static method & field here.
}

Dann sieht deine Klasse aus wie

    class Student(var name: String, var city: String, var rollNumber: Double = 0.0) {

    // use companion object structure
    companion object {

        // below method will work as static method
        fun getUniversityName(): String = "MBSTU"

        // below field will work as static field
        var totalStudent = 30
    }
}

Dann können Sie diese statischen Methoden und Felder auf diese Weise verwenden.

println("University : " + Student.getUniversityName() + ", Total Student: " + Student.totalStudent)
    // Output:
    // University : MBSTU, Total Student: 30

1

In Kotlin gibt es kein statisches Schlüsselwort. kotlin docs empfiehlt die Verwendung von Funktionen auf Paketebene, wenn Sie DRY folgen möchten. Erstellen Sie eine Datei mit der Erweiterung .kt und fügen Sie Ihre Methode ein.

package p
    fun m(){
    //fun body
    }

Nach der Kompilierung hat m eine Signatur der öffentlichen statischen endgültigen Leere

und

import p.m


0

Sie können die statische Funktionalität in Kotlin von Companion Objects erreichen

  • Durch Hinzufügen eines Begleiters zur Objektdeklaration kann die Statik hinzugefügt werden einem Objekt Funktionalität werden, obwohl das eigentliche statische Konzept in Kotlin nicht vorhanden ist.
  • Ein Begleitobjekt kann auch auf alle Mitglieder der Klasse zugreifen, einschließlich der privaten Konstruktoren.
  • Ein Begleitobjekt wird initialisiert, wenn die Klasse instanziiert wird.
  • Ein Begleitobjekt kann nicht außerhalb der Klasse deklariert werden.

    class MyClass{
    
        companion object {
    
            val staticField = "This is an example of static field Object Decleration"
    
            fun getStaticFunction(): String {
                return "This is example of static function for Object Decleration"
            }
    
        }
    }

Mitglieder des Begleitobjekts können aufgerufen werden, indem einfach der Klassenname als Qualifikationsmerkmal verwendet wird:

Ausgabe:

MyClass.staticField // This is an example of static field Object Decleration

MyClass.getStaticFunction() : // This is an example of static function for Object Decleration

0

Alle statischen Elemente und Funktionen sollten sich im Begleitblock befinden

  companion object {
    @JvmStatic
    fun main(args: Array<String>) {
    }

    fun staticMethod() {
    }
  }

0

Viele Leute erwähnen Begleitobjekte, was richtig ist. Aber nur damit Sie wissen, können Sie auch jede Art von Objekt verwenden (mit dem Objektschlüsselwort, nicht mit der Klasse), dh

object StringUtils {
    fun toUpper(s: String) : String { ... }
}

Verwenden Sie es wie jede statische Methode in Java:

StringUtils.toUpper("foobar")

Diese Art von Muster ist in Kotlin jedoch nutzlos. Eine seiner Stärken besteht darin, dass keine Klassen mit statischen Methoden mehr benötigt werden. Abhängig von Ihrem Anwendungsfall ist es besser, stattdessen globale, Erweiterungs- und / oder lokale Funktionen zu verwenden. Wo ich arbeite, definieren wir häufig globale Erweiterungsfunktionen in einer separaten, flachen Datei mit der Namenskonvention: [className] Extensions.kt, dh FooExtensions.kt. Typischerweise schreiben wir Funktionen jedoch dort, wo sie innerhalb ihrer Betriebsklasse oder ihres Objekts benötigt werden.


0

In Java können wir unten schreiben

class MyClass {
  public static int myMethod() { 
  return 1;
  }
}

In Kotlin können wir unten schreiben

class MyClass {
  companion object {
     fun myMethod() : Int = 1
  }
}

Ein Begleiter wird in Kotlin als statisch verwendet.


0

Der Kotlin-Dokumentanbieter bietet drei Möglichkeiten, um dies zu tun. Die erste besteht darin, die Funktion im Paket ohne Klasse zu definieren:

package com.example

fun f() = 1

Die zweite ist die Verwendung der Annotation @JvmStatic:

package com.example

class A{
@JvmStatic
fun f() = 1
}

und das dritte ist das Begleitobjekt verwenden:

package com.example

clss A{
companion object{
fun f() = 1
}
}

-1

Wenn Sie eine Funktion oder Eigenschaft benötigen, die an eine Klasse und nicht an Instanzen derselben gebunden werden soll, können Sie sie in einem Begleitobjekt deklarieren:

class Car(val horsepowers: Int) {
    companion object Factory {
        val cars = mutableListOf<Car>()

        fun makeCar(horsepowers: Int): Car {
            val car = Car(horsepowers)
            cars.add(car)
            return car
        }
    }
}

Das Begleitobjekt ist ein Singleton, und auf seine Mitglieder kann direkt über den Namen der enthaltenen Klasse zugegriffen werden

val car = Car.makeCar(150)
println(Car.Factory.cars.size)

Es sieht so aus, als ob die akzeptierte Antwort bereits Begleitobjekte beschreibt. So sind viele der anderen Antworten. Bietet Ihre Antwort etwas Neues?
Sneftel


-2

Sie können verwenden Companion Objects - kotlinlang verwenden

Was gezeigt werden kann, indem zuerst diese Schnittstelle erstellt wird

interface I<T> {

}

Dann müssen wir eine Funktion innerhalb dieser Schnittstelle erstellen:

fun SomeFunc(): T

Danach brauchen wir eine Klasse:

class SomeClass {}

Innerhalb dieser Klasse benötigen wir ein Begleitobjekt innerhalb dieser Klasse:

companion object : I<SomeClass> {}

In diesem Begleitobjekt brauchen wir diese alte SomeFuncFunktion, aber wir müssen sie überschreiben:

override fun SomeFunc(): SomeClass = SomeClass()

Schließlich brauchen wir unter all dieser Arbeit etwas, um diese statische Funktion zu stärken. Wir brauchen eine Variable:

var e:I<SomeClass> = SomeClass()
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.