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:
classFoo{publicstaticint a(){return1;}}
wird werden
classFoo{
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.
Eine Objektdeklaration innerhalb einer Klasse kann mit dem Schlüsselwort Companion gekennzeichnet werden:
classMyClass{
companion objectFactory{
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
classFoo{
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:
classFoo{
companion objectBlah{
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).
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.
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:
Deklarieren Sie a companion object, um eine statische Methode / Variable einzuschließen
classFoo{
companion object{
fun foo()= println("Foo")
val bar ="bar"}}
Verwenden :
Foo.foo()// Outputs Foo
println(Foo.bar)// Outputs bar
B. Neuer Kotlin-Weg
Deklarieren Sie direkt in einer Datei ohne Klasse in einer .ktDatei.
fun foo()= println("Foo")
val bar ="bar"
Verwenden Sie die methods/variablesmit ihren Namen . ( Nach dem Import )
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
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
classClassName{
companion object{
fun helloWord(str:String):String{return stringValue
}}}
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
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 .
classMyClass{
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.
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 Javapackage com.frybits
classKotlinClass{
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;classJavaClass{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 Javapackage com.frybits
classKotlinClass{
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].@JvmFieldvar 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 insteadconst 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@JvmStaticvar cat:Int=9}}
Java
package com.frybits;classJavaClass{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 variableconst 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 functionsvar foo =1//This lets us use direct access now@JvmFieldvar 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;classJavaClass{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 functionKotlinUtils.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 likeKotlinUtils.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 Javapackage com.frybits
objectKotlinClass{//No need for the 'class' keyword here.//Direct access to this variableconst val foo:Int=1//Tells Java this can be accessed directly from [KotlinClass]@JvmStaticvar 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;classJavaClass{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 annotationsKotlinClass.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);}}
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.
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.
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:
classMainActivity: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:
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
objectConst{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"
@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).
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)}}}
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
classStudent(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 fieldvar 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
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
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.
classMyClass{
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 DeclerationMyClass.getStaticFunction():// This is an example of static function for Object Decleration
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
objectStringUtils{
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.
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:
classCar(val horsepowers:Int){
companion objectFactory{
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?
Antworten:
Sie platzieren die Funktion im "Begleitobjekt".
Also der Java-Code wie folgt:
wird werden
Sie können es dann aus dem Kotlin-Code als verwenden
Aber innerhalb von Java-Code müssten Sie es als aufrufen
(Was auch innerhalb von Kotlin funktioniert.)
Wenn Sie das
Companion
Bit nicht angeben müssen , können Sie entweder eine@JvmStatic
Anmerkung hinzufügen oder Ihre Begleitklasse benennen.Aus den Dokumenten :
Das Hinzufügen der
@JvmStatic
Anmerkung sieht folgendermaßen ausund 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
Companion
Name nur nicht gefällt, können Sie auch einen expliziten Namen für das Begleitobjekt angeben, der folgendermaßen aussieht:Damit können Sie es von Kotlin auf die gleiche Weise aufrufen, aber von Java-ähnlich
Foo.Blah.a()
(was auch in Kotlin funktioniert).quelle
fun a(): Int { return 1 }
oder sogarfun a(): Int = 1
fun a() = 1
.Factory
ist 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 .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
Verwendungszweck
Alternative
Sie können die Funktion jetzt aufrufen mit:
oder wenn Sie das Schlüsselwort import nicht verwenden:
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.
quelle
class FooPackage
mit allen Eigenschaften und Funktionen der obersten Ebene erstellen und alle Ihre Verweise entsprechend an diese weiterleiten. Weitere Infos von Jetbrains.bar()
, der Dateiname keine Rolle spielt, Sie sie benennen könnenBarUtils.kt
oder was auch immer, dann, wie der Text sagt, werden Sie sie mit importierenimport <package name>.bar
A. Alter Java-Weg:
Deklarieren Sie a
companion object
, um eine statische Methode / Variable einzuschließenVerwenden :
B. Neuer Kotlin-Weg
Deklarieren Sie direkt in einer Datei ohne Klasse in einer
.kt
Datei.Verwenden Sie die
methods/variables
mit ihren Namen . ( Nach dem Import )Verwenden :
quelle
INSTANCE
Schlüsselwort haben, wieFoo.INSTANCE.sayFoo()
static CLASS
nicht nur wollenstatic methdos
. Denn mit Begleitobjekten können Sie die übergeordnete Klasse weiterhin instanziieren.val
ist nicht statisch, es entsprichtstatic final
JavaVerwenden 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
Wenn Sie es von Java aus aufrufen müssen:
Ignorieren Sie in Kotlin INSTANCE.
quelle
Das hat auch bei mir funktioniert
von Kotlin
von Java
quelle
quelle
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:
quelle
Es gibt zwei Möglichkeiten, wie Sie statisch in Kotlin anwenden können
Erstellen Sie zuerst ein Begleitobjekt unter Klasse
Zum Beispiel:
Sie können diese Funktion als aufrufen
Eine andere Möglichkeit besteht darin, eine Objektklasse zu erstellen
Viel Spaß beim Codieren!
quelle
Test.Companion.isCheck(2)
) zeigt IDE Warnungen an und sagtCompanion reference is redundant
. Es kann auf reduziert werdenTest.isCheck(2)
und die reduzierte Form kommt dem Java-Äquivalent näher.Kotlin hat kein statisches Schlüsselwort. Du hast das für Java benutzt
und für Kotlin
Rufen Sie nach Java
Rufen Sie nach Kotlin
Ich denke, es funktioniert perfekt.
quelle
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 .
Sie können die oben definierte Funktion aufrufen, da Sie jede Funktion in Companion Object aufrufen.
quelle
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
static
Interop: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.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
static
Funktionen / Felder in Java verwendet werden können.Eine weitere bemerkenswerte Erwähnung, die in Java als "statische" Felder verwendet werden kann, sind Kotlin-
object
Klassen. 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-declarationsFür den Zugriff auf den Singleton wird jedoch ein spezielles
INSTANCE
Objekt erstellt, dessen Handhabung genauso umständlichCompanion
ist wie es ist. So verwenden Sie Anmerkungen, umstatic
Java ein sauberes Gefühl zu verleihen :quelle
Um es kurz zu machen, könnten Sie "Companion Object" verwenden , um in die statische Welt von Kotlin zu gelangen, wie:
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.
quelle
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:
Kotlin-Code:
quelle
Sie müssen lediglich ein Begleitobjekt erstellen und die Funktion darin einfügen
So rufen Sie die Methode aus einer Kotlin-Klasse auf:
oder Import verwenden
So rufen Sie die Methode von einer Java-Klasse aus auf:
oder indem Sie der Methode die Annotation @JvmStatic hinzufügen
oder beides, indem Sie der Methode eine @ JvmStatic-Annotation hinzufügen und einen statischen Import in Java durchführen
quelle
Für Java:
Äquivalenter Kotlin-Code:
Das Äquivalent zu statischen Java-Methoden ist also die Objektklasse in Kotlin.
quelle
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:
Eine weitere Aktivität, bei der Wert benötigt wird:
quelle
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
Sie können es in Kotlin- und Java-Code verwenden
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
Sie können es in Kotlin-Code verwenden
Sie können es in Java-Code verwenden
quelle
Schreiben Sie sie direkt in Dateien.
In Java (hässlich):
In Kotlin:
Diese beiden Codeteile werden nach der Kompilierung gleichgestellt (selbst der kompilierte Dateiname
file:JvmName
wird verwendet, um den kompilierten Dateinamen zu steuern, der unmittelbar vor der Deklaration des Paketnamens stehen sollte).quelle
Verwenden Sie
@JVMStatic
Annotationquelle
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 .
Dann sieht deine Klasse aus wie
Dann können Sie diese statischen Methoden und Felder auf diese Weise verwenden.
quelle
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.
Nach der Kompilierung hat m eine Signatur der öffentlichen statischen endgültigen Leere
und
☺
quelle
Sie können die statische Funktionalität in Kotlin von Companion Objects erreichen
Ein Begleitobjekt kann nicht außerhalb der Klasse deklariert werden.
Mitglieder des Begleitobjekts können aufgerufen werden, indem einfach der Klassenname als Qualifikationsmerkmal verwendet wird:
Ausgabe:
quelle
Alle statischen Elemente und Funktionen sollten sich im Begleitblock befinden
quelle
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
Verwenden Sie es wie jede statische Methode in Java:
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.
quelle
In Java können wir unten schreiben
In Kotlin können wir unten schreiben
Ein Begleiter wird in Kotlin als statisch verwendet.
quelle
Der Kotlin-Dokumentanbieter bietet drei Möglichkeiten, um dies zu tun. Die erste besteht darin, die Funktion im Paket ohne Klasse zu definieren:
Die zweite ist die Verwendung der Annotation @JvmStatic:
und das dritte ist das Begleitobjekt verwenden:
quelle
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:
Das Begleitobjekt ist ein Singleton, und auf seine Mitglieder kann direkt über den Namen der enthaltenen Klasse zugegriffen werden
quelle
Sie können verwenden Companion Objects - kotlinlang verwenden
Was gezeigt werden kann, indem zuerst diese Schnittstelle erstellt wird
Dann müssen wir eine Funktion innerhalb dieser Schnittstelle erstellen:
Danach brauchen wir eine Klasse:
Innerhalb dieser Klasse benötigen wir ein Begleitobjekt innerhalb dieser Klasse:
In diesem Begleitobjekt brauchen wir diese alte
SomeFunc
Funktion, aber wir müssen sie überschreiben:Schließlich brauchen wir unter all dieser Arbeit etwas, um diese statische Funktion zu stärken. Wir brauchen eine Variable:
quelle