it-swarm.com.de

Was ist das Äquivalent zu Java statischen Methoden in Kotlin?

Es gibt kein static Schlüsselwort in Kotlin.

Wie kann eine static Java -Methode in Kotlin am besten dargestellt werden?

493
pdeva

Sie platzieren die Funktion im "Begleitobjekt".

Der Java Code sieht also so aus:

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

wird werden

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

Sie können es dann innerhalb von Kotlin-Code als verwenden

Foo.a();

Aber aus dem Code Java heraus müssten Sie ihn als aufrufen

Foo.Companion.a();

(Das funktioniert auch innerhalb von Kotlin.)

Wenn Sie das Companion -Bit nicht angeben möchten, können Sie entweder eine @JvmStatic -Anmerkung hinzufügen oder Ihre Companion-Klasse benennen.

Aus dem docs :

Begleitende Objekte

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

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

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

val instance = MyClass.create()

...

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

Das Hinzufügen der Anmerkung @JvmStatic sieht folgendermaßen aus

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

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

Wenn der Name Companion nicht gefällt, können Sie auch einen expliziten Namen für das Companion-Objekt eingeben, 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 wie Foo.Blah.a() (was auch in Kotlin funktioniert).

704

Docs empfiehlt, die meisten Anforderungen für statische Funktionen mit Funktionen auf Paketebene zu lösen. 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() = {}

Verwendung

import foo.bar

Alternativ

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, können Sie über das Stammverzeichnis auf die Funktion zugreifen.

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.

111
Henrik F.

A. Old Java Way:

  1. Deklarieren Sie einen companion object, um ein statisches Methode/Variable einzuschließen

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

    Foo.foo()        // Output Foo    
    println(Foo.bar) .  // Output Bar
    


B. New Kotlin Weg

  1. Deklarieren Sie direkt in der Datei ohne Klasse in einer .kt -Datei.

    fun foo() = println("Foo")
    val bar ="bar"
    
  2. Verwenden Sie den methods/variables mit ihrem Namen. (Nach dem Importieren)

    Verwenden :

    foo()        // Output Foo    
    println(bar) .  // Output Bar
    

24
erluxman

Verwenden Sie Objekt, um val/var/method darzustellen und statisch zu machen. Sie können auch object anstelle von singleton class verwenden. Sie können Begleiter 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 INSTANZ.

19
Asharali V U

Das hat auch bei mir geklappt

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

von Kotlin

Bell.ring()

von Java

Bell.ring()
7
Samuel

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

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

    }
}
5
Umesh Maharjan

In Kotlin können Sie auf zwei Arten statische Aufladung anwenden

Machen 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!

4
Android Geek

Kotlin hat kein statisches Schlüsselwort. Sie haben das für Java verwendet

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

und für Kotlin

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

Aufruf für Java

AppHelper.getAge();

Ruf nach Kotlin

AppHelper.Companion.getAge();

Ich denke, es funktioniert perfekt.

3
Shohel Rana

Um es kurz zu machen, können Sie "Begleiterobjekt" 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 erzeugen, benutze "const val" wie im Code. Vermeiden Sie jedoch die statischen Klassen, da dies beim Testen von Einheiten mit Mockito! zu Problemen führt.

3
CodeRanger

Ich möchte etwas zu den obigen Antworten 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 mit Kotlin Extensions weitere statische Funktionen hinzufügen können.

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

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

Und Sie können die oben definierte Funktion aufrufen, wie Sie jede Funktion in Companion Object aufrufen werden.

3
SVB-knowmywork

Auch wenn dies jetzt etwas mehr als 2 Jahre alt ist und viele gute Antworten hatte, fehlen mir einige andere Möglichkeiten, um "statische" Kotlin-Felder zu erhalten. Hier ist eine Beispielanleitung für Kotlin-Java static interop:

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

Die Antwort von Michael Anderson bietet mehr Tiefe als diese und sollte für dieses Szenario unbedingt herangezogen werden.


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

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 Eigenschaften von Kotlin ist, dass Sie Funktionen und Variablen der obersten Ebene erstellen können. Dies macht es sehr einfach, "klassenlose" Listen von konstanten Feldern und Funktionen zu erstellen, die wiederum als static Funktionen/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 object -Klassen. Hierbei handelt es sich um Nullparameter-Singleton-Klassen, die bei der ersten Verwendung nur schleppend instanziiert werden. Weitere Informationen dazu finden Sie hier: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations

Um auf den Singleton zuzugreifen, wird jedoch ein spezielles INSTANCE -Objekt erstellt, dessen Behandlung genauso umständlich ist wie die von Companion. So verwenden Sie Annotationen, um in Java ein sauberes static Gefühl zu erzeugen:

Szenario 4: Verwenden von object Klassen

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);
    }
}
2
Pablo Baxter

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 Verwenden des Imports

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

So rufen Sie die Methode von einer Klasse Java auf:

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

oder durch Hinzufügen von @ JvmStatic Annotation zu der Methode

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

oder beides, indem Sie der Methode die Annotation @JvmStatic 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
yasincidem

Companion Objects ist die Alternative des statischen Schlüsselworts Java, und Sie können eine Klasse oder Methode als statisch definieren, indem Sie sie als Companion Objects deklarieren.
Sie müssen Begleitobjekte auch dann nicht mit dem Klassennamen qualifizieren, wenn Sie sie aus derselben Klasse aufrufen.

Zum Beispiel:

class SomeClass() {

    val id: Int

    init {
       id = nextId++       
    }

    private companion object {
       var nextId = 1
    }
}

fun main(args: Array<String>) {
    repeat(2) { 
        println(SomeClass().id)
    }
} 
2
Shubham Mittal

Sie können andere Objekte als Begleitobjekte verwenden

object Utils {
    fun someFunction()
}

Das wird also so aussehen, wenn die Methode aufgerufen wird.

Utils.someFunction()
2
dr3k

erstellen Sie ein Companion-Objekt und markieren Sie die Methode mit jvmstatic-Annotation

2
user9092442

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

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



//Kotlin
class Util {
    companion object {
        @JvmStatic
        fun capitalize(text:String): String {
            return text.toUpperCase()
        }
    }
}
2
Lalit Behera

Verwenden Sie die Funktion in "Begleitobjekt oder benanntes Objekt".

Siehe Beispiel eines Begleitobjekts:

   class Foo {
  companion object {
     fun square(x : Int) : Int = x*x
  }
}

Siehe das Beispiel des benannten Objekts

object Foo{
   fun square(x : Int) : Int = x*x
}

Sie können mit zugreifen

val k = Foo.square(12)
2
Sabin ks

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 gleichgesetzt (selbst der kompilierte Dateiname, der file:JvmName, wird zur Steuerung des kompilierten Dateinamens verwendet, der direkt vor der Deklaration des Paketnamens stehen sollte).

1
ice1000

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

Sie sollten Begleitobjekt Block innerhalb Ihrer Klasse deklarieren.

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

Dann sieht deine Klasse so aus

    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
Shihab Uddin

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}

Für das Äquivalent von Java statischen Methoden ist die Objektklasse in Kotlin.

1
Paulami Biswas

Verwenden Sie @JVMStatic Annotation

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
ZafarHussain

Alle statischen Elemente und Funktionen sollten sich im Companion Block befinden

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

    fun staticMethod() {
    }
  }
0
Rahul

In Java können wir wie folgt schreiben

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

In Kotlin können wir wie folgt schreiben

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

ein Begleiter wird in Kotlin als statisch verwendet.

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 Schlüsselwort object, nicht class), d. H.

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 mit statischen Methoden gefüllten Klassen mehr benötigt werden. Je nach Anwendungsfall ist es sinnvoller, stattdessen globale, Erweiterungs- und/oder lokale Funktionen zu verwenden. Wo ich arbeite, definieren wir globale Erweiterungsfunktionen häufig in einer separaten, flachen Datei mit der Namenskonvention: [className] Extensions.kt, d. H. FooExtensions.kt. Typischerweise schreiben wir Funktionen dort, wo sie in ihrer Operationsklasse oder ihrem Objekt benötigt werden.

0
pranalli

Sie können die statische Funktionalität in Kotlin durch Begleitobjekte erreichen

  • Das Hinzufügen von Begleiter zur Objektdeklaration ermöglicht das Hinzufügen der statischen Funktionalität zu einem Objekt, obwohl das eigentliche statische Konzept in Kotlin nicht existiert.
  • Ein Companion-Objekt 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 Companion-Objekts 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
Waqar UlHaq

Der kotlin-Dokumentenanbieter bietet drei Möglichkeiten, dies zu tun: Die erste ist die Funktion define in package ohne Klasse:

package com.example

fun f() = 1

die zweite ist use @JvmStatic Annotation:

package com.example

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

und der dritte ist use companion object:

package com.example

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

Der Java Code sieht wie folgt aus:

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

wird wie folgt in kotlin:

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

Mithilfe der Annotation @JvmStatic in der JVM können jedoch Mitglieder von Begleitobjekten als echte statische Methoden und Felder generiert werden.

0
hetsgandhi