Radzimy: Kotlin usunął staty w stylu Java, aby zachęcić do łatwiejszych w utrzymaniu (ośmielę się powiedzieć „lepszych”) praktyk kodowania. Globale statyczne są generalnie przeciwne paradygmatowi OOP, ale mogą być całkiem wygodne. Dlatego Kotlin dostarczył nam towarzyszy, bardziej przyjazny dla OOP sposób posiadania statyki.
Nicholas Miller,
Według Google'a Kotlin jest teraz preferowanym językiem do tworzenia Androida.
AFD
@NicholasMiller dlaczego jest bardziej przyjazny dla OOP? Myślę, że łatwiej jest czytać i pisać bez powtarzającej się nuty statycznej (płyta kotła). Czy jest jeszcze jeden dobry powód?
Torben G
Odpowiedzi:
887
Umieszczasz funkcję w „obiekcie towarzyszącym”.
Więc kod Java taki jak ten:
classFoo{publicstaticint a(){return1;}}
stanie się
classFoo{
companion object{
fun a():Int=1}}
Następnie możesz użyć go z kodu Kotlin jako
Foo.a();
Ale z poziomu kodu Java należy nazwać go jako
Foo.Companion.a();
(Który działa również z poziomu Kotlina.)
Jeśli nie chcesz określać Companionbitu, możesz dodać@JvmStatic adnotację lub nazwać swoją klasę towarzyszącą.
Deklaracja obiektu w klasie może być oznaczona słowem kluczowym towarzyszącym:
classMyClass{
companion objectFactory{
fun create():MyClass=MyClass()}}
Członkowie obiektu towarzyszącego można wywoływać, używając po prostu nazwy klasy jako kwalifikatora:
val instance =MyClass.create()
...
Jednak w JVM możesz mieć elementy obiektów towarzyszących wygenerowane jako rzeczywiste metody statyczne i pola, jeśli użyjesz @JvmStatic
adnotacji. Aby uzyskać więcej informacji, zobacz sekcję „Interoperacyjność Java”.
Dodanie @JvmStaticadnotacji wygląda następująco
classFoo{
companion object{@JvmStatic
fun a():Int=1;}}
i wtedy będzie istniał jako prawdziwa statyczna funkcja Java, dostępna zarówno z Javy, jak i Kotlin as Foo.a().
Jeśli nie podoba mu się Companionnazwa, możesz także podać jawną nazwę dla obiektu towarzyszącego, który wygląda następująco:
classFoo{
companion objectBlah{
fun a():Int=1;}}
co pozwoli ci nazywać to z Kotlina w ten sam sposób, ale z języka java Foo.Blah.a()(który będzie działał również w Kotlinie).
W Kotlinie będzie fun a(): Int { return 1 }lub nawetfun a(): Int = 1
Dmitrij Zajcew
3
@DmitryZaitsev lub nawet fun a() = 1.
Moira
Co znaczy Factory?
Bagus Aji Santoso
@BagusAjiSantoso Factoryto nazwa obiektu towarzyszącego - ale do czego można go użyć? Nie mam pojęcia, ale byłem zainteresowany, więc stworzyłem pytanie poświęcone temu tematowi : stackoverflow.com/q/45853459/221955 .
Michael Anderson
1
@ Yajairo87 Myślę, że to, o co pytasz, to zbyt wiele, aby je tutaj skomentować - dlatego stworzyłem pytanie, które dotyczyło tego bezpośrednio: stackoverflow.com/questions/47046474/...
Michael Anderson
154
Docs zaleca rozwiązanie większości potrzeb związanych z funkcjami statycznymi za pomocą funkcji na poziomie pakietu . Są po prostu zadeklarowane poza klasą w pliku kodu źródłowego. Pakiet pliku można określić na początku pliku za pomocą słowa kluczowego package.
Deklaracja
package foo
fun bar()={}
Stosowanie
import foo.bar
Alternatywnie
import foo.*
Możesz teraz wywołać funkcję za pomocą:
bar()
lub jeśli nie używasz słowa kluczowego import:
foo.bar()
Jeśli nie określisz pakietu, funkcja będzie dostępna z poziomu katalogu głównego.
Jeśli masz tylko doświadczenie z Javą, może się to wydawać trochę dziwne. Powodem jest to, że kotlin nie jest językiem ściśle obiektowym. Można powiedzieć, że obsługuje metody poza klasami.
Edycja: Dokonali edycji dokumentacji, aby nie zawierać już zdania na temat rekomendowania funkcji na poziomie pakietu. Jest to oryginał, o którym mowa powyżej.
Zauważ, że pod maską te funkcje „najwyższego poziomu” lub „pakietu” są w rzeczywistości skompilowane we własnej klasie. W powyższym przykładzie kompilator utworzy class FooPackagewszystkie właściwości i funkcje najwyższego poziomu i odpowiednio skieruje do nich wszystkie odniesienia. Więcej informacji z jetbrains.
Mitchell Tracy,
29
+1 Za wyjaśnienie, jak zrobić odpowiednik w Kotlinie zamiast tylko lustrzanego odpowiednika w Javie.
feniks
1
To powinna być zaakceptowana odpowiedź lub mod powinien zaktualizować zaakceptowaną odpowiedź, aby zawierała funkcje na poziomie pakietu
To jak dotąd lepsze rozwiązanie. Chciałem tylko wyjaśnić, że tam, gdzie zdefiniujesz funkcję, bar()nie ma znaczenia nazwa pliku, możesz go nazwać BarUtils.ktlub cokolwiek, a następnie, jak mówi tekst, zaimportujesz go za pomocąimport <package name>.bar
Mariano Ruiz
33
A. Old Java Way:
Zadeklaruj a, companion objectaby załączyć metodę / zmienną statyczną
classFoo{
companion object{
fun foo()= println("Foo")
val bar ="bar"}}
Posługiwać się :
Foo.foo()// Outputs Foo
println(Foo.bar)// Outputs bar
B. Nowa droga Kotlin
Deklaruj bezpośrednio w pliku bez klasy w .ktpliku.
fun foo()= println("Foo")
val bar ="bar"
Użyj methods/variablesz ich nazwami . ( Po ich zaimportowaniu )
Jeśli próbuję zainicjować w jakiejś innej klasie, daje java.lang.ExceptionInInitializerError i używam var zamiast val
Sudarshan
4
Wywołania metod muszą mieć INSTANCEsłowo kluczowe, takie jak:Foo.INSTANCE.sayFoo()
Raeglan
Myślę, że to rozwiązanie jest preferowanym sposobem, jeśli chcesz static CLASSnie tylko static methdos. Ponieważ w przypadku obiektów towarzyszących nadal można utworzyć instancję klasy nadrzędnej.
Fabriciorissetto
valnie jest statyczny, to odpowiednik static finalw Javie
Farid
23
Użyj obiektu do reprezentowania metody val / var /, aby uzyskać statyczną wartość. Możesz także użyć obiektu zamiast klasy singleton. Możesz użyć towarzysza, jeśli chcesz uczynić statycznym wewnątrz klasy
Ten fragment kodu może być rozwiązaniem, ale wyjaśnienie naprawdę pomaga poprawić jakość posta. Pamiętaj, że w przyszłości odpowiadasz na pytanie czytelników, a ci ludzie mogą nie znać przyczyn Twojej sugestii kodu.
Narendra Jadhav
5
Musisz przekazać obiekt towarzyszący dla metody statycznej, ponieważ kotlin nie ma słowa kluczowego statycznego - Członkowie obiektu towarzyszącego można wywołać, używając po prostu nazwy klasy jako kwalifikatora:
package xxx
classClassName{
companion object{
fun helloWord(str:String):String{return stringValue
}}}
Przy pierwszym użyciu (tj. Test.Companion.isCheck(2)) IDE pokazuje ostrzeżenia i powiedz Companion reference is redundant. Można go zredukować, Test.isCheck(2)a zredukowana forma jest bardziej zbliżona do odpowiednika Java.
VSB
3
Kotlin nie ma statycznego słowa kluczowego. Użyłeś tego dla java
Tak, możesz zdefiniować funkcje w plikach kodu źródłowego (poza klasą). Lepiej jest jednak zdefiniować funkcje statyczne w klasie za pomocą Companion Object, ponieważ można dodać więcej funkcji statycznych, korzystając z rozszerzeń Kotlin .
classMyClass{
companion object{//define static functions here}}//Adding new static function
fun MyClass.Companion.newStaticFunction(){// ...}
I możesz wywołać powyższą funkcję, tak jak wywołasz dowolną funkcję w obiekcie Companion.
Mimo że ma on już nieco ponad 2 lata i wiele wspaniałych odpowiedzi, widzę inne sposoby uzyskania „statycznych” pól Kotlina. Oto przykładowy przewodnik dla interakcji Kotlin-Java static:
Scenariusz 1: Tworzenie metody statycznej w Kotlin dla 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}}
Jawa
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);}}
Odpowiedź Michaela Andersona zapewnia więcej głębi i na pewno należy się odwoływać do tego scenariusza.
Następny scenariusz obsługuje tworzenie pól statycznych w Kotlin, dzięki czemu Java nie musi wywoływać KotlinClass.foo()tych przypadków, w których nie chcesz funkcji statycznej.
Scenariusz 2: Tworzenie zmiennej statycznej w Kotlin dla 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}}
Jawa
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);}}
Jedną z wielkich zalet Kotlina jest możliwość tworzenia funkcji i zmiennych najwyższego poziomu. To sprawia, że warto tworzyć „bezklasowe” listy stałych pól i funkcji, które z kolei mogą być używane jako staticfunkcje / pola w Javie.
Scenariusz 3: Dostęp do pól i funkcji najwyższego poziomu w Kotlin z Java
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!")}
Jawa
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);}}
Kolejną godną uwagi wzmianką, która może być używana w Javie jako pola „statyczne”, są objectklasy Kotlin . Są to klasy singletonów o zerowym parametrze, które są tworzone leniwie przy pierwszym użyciu. Więcej informacji na ich temat można znaleźć tutaj: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations
Jednak, aby uzyskać dostęp do singletonu, INSTANCEtworzony jest specjalny obiekt, który jest tak samo niewygodny, jak się nim Companionzajmuje. Oto jak używać adnotacji, aby zapewnić czysty staticwygląd w Javie:
Scenariusz 4: Korzystanie z objectklas
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'?"}
Jawa
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);}}
Krótko mówiąc, możesz użyć „obiektu towarzyszącego”, aby dostać się do statycznego świata Kotlin, takiego jak:
companion object{const val TAG ="tHomeFragment"
fun newInstance()=HomeFragment()}
i aby zrobić stałe pole, użyj „const val” jak w kodzie. ale staraj się unikać klas statycznych, ponieważ utrudnia to testowanie jednostkowe przy użyciu Mockito !.
Dokładna konwersja metody statycznej Java na ekwiwalent kotlin byłaby taka. np. tutaj klasa util ma jedną metodę statyczną, która byłaby równoważna zarówno w java, jak i kotlin. Zastosowanie @JvmStatic jest ważne.
Dla systemu Android za pomocą ciągu od pojedynczego działania do wszystkich niezbędnych działań. Tak jak statyczny w java
public final static String TEA_NAME = "TEA_NAME";
Równoważne podejście w Kotlinie:
classMainActivity:AppCompatActivity(){
companion object{const val TEA_NAME ="TEA_NAME"}override fun onCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)}}
Kolejne działanie, w którym potrzebna jest wartość:
@file:JvmName("XxxUtils")package xxx
fun xxx(xxx:Xxx):Yyy= xxx.xxx()
Te dwa fragmenty kodów są równoważone po kompilacji (nawet nazwa skompilowanego pliku file:JvmNamesłuży do kontrolowania nazwy skompilowanego pliku, który należy umieścić tuż przed deklaracją nazwy pakietu).
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)}}}
Niech masz klasowego ucznia . I masz jedną metodę statyczną getUniversityName () i jedno pole statyczne o nazwie totalStudent .
Powinieneś zadeklarować blok obiektów towarzyszących w swojej klasie.
companion object{// define static method & field here.}
Wtedy twoja klasa wygląda
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}}
Następnie możesz użyć tych statycznych metod i pól w ten sposób.
println("University : "+Student.getUniversityName()+", Total Student: "+Student.totalStudent)// Output:// University : MBSTU, Total Student: 30
W kotlin nie ma statycznego słowa kluczowego. kotlin docs zaleca korzystanie z funkcji na poziomie pakietu, jeśli chcesz stosować DRY. Utwórz plik z rozszerzeniem .kt i umieść w nim swoją metodę.
package p
fun m(){//fun body}
po kompilacji m będzie miał podpis publicznej ostatecznej nieważności
Funkcję statyczną można osiągnąć w Kotlin dzięki obiektom towarzyszącym
Dodanie elementu towarzyszącego do deklaracji obiektu pozwala na dodanie elementu
statycznego funkcji do obiektu, nawet jeśli rzeczywista koncepcja statyczna nie istnieje w Kotlinie.
Obiekt towarzyszący może również uzyskać dostęp do wszystkich członków klasy, w tym do prywatnych konstruktorów.
Obiekt towarzyszący jest inicjowany podczas tworzenia instancji klasy.
Obiekt towarzyszący nie może zostać zadeklarowany poza klasą.
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"}}}
Członkowie obiektu towarzyszącego można wywoływać, używając po prostu nazwy klasy jako kwalifikatora:
Wynik:
MyClass.staticField // This is an example of static field Object DeclerationMyClass.getStaticFunction():// This is an example of static function for Object Decleration
Wiele osób wspomina o obiektach towarzyszących, co jest poprawne. Ale dla pewności możesz użyć dowolnego obiektu (używając słowa kluczowego object, a nie klasy), tj.
objectStringUtils{
fun toUpper(s:String):String{...}}
Użyj go tak jak każdej metody statycznej w Javie:
StringUtils.toUpper("foobar")
Ten rodzaj wzorca jest jednak trochę bezużyteczny w Kotlinie, jedną z jego zalet jest to, że pozbywa się potrzeby klas wypełnionych metodami statycznymi. Bardziej właściwe jest korzystanie z funkcji globalnych, rozszerzeń i / lub lokalnych, w zależności od przypadku użycia. Tam, gdzie pracuję, często definiujemy globalne funkcje rozszerzeń w osobnym, płaskim pliku z konwencją nazewnictwa: [nazwa_klasy] Extensions.kt tj. FooExtensions.kt. Ale częściej piszemy funkcje tam, gdzie są potrzebne w swojej klasie operacyjnej lub obiekcie.
Jeśli potrzebujesz funkcji lub właściwości do powiązania z klasą, a nie z jej instancjami, możesz zadeklarować ją w obiekcie towarzyszącym:
classCar(val horsepowers:Int){
companion objectFactory{
val cars = mutableListOf<Car>()
fun makeCar(horsepowers:Int):Car{
val car =Car(horsepowers)
cars.add(car)return car
}}}
Obiekt towarzyszący jest singletonem, a do jego elementów można uzyskać bezpośredni dostęp poprzez nazwę klasy zawierającej
val car =Car.makeCar(150)
println(Car.Factory.cars.size)
Wygląda na to, że zaakceptowana odpowiedź już opisuje obiekty towarzyszące. Podobnie jak wiele innych odpowiedzi. Czy twoja odpowiedź zawiera coś nowego?
Odpowiedzi:
Umieszczasz funkcję w „obiekcie towarzyszącym”.
Więc kod Java taki jak ten:
stanie się
Następnie możesz użyć go z kodu Kotlin jako
Ale z poziomu kodu Java należy nazwać go jako
(Który działa również z poziomu Kotlina.)
Jeśli nie chcesz określać
Companion
bitu, możesz dodać@JvmStatic
adnotację lub nazwać swoją klasę towarzyszącą.Z dokumentów :
Dodanie
@JvmStatic
adnotacji wygląda następującoi wtedy będzie istniał jako prawdziwa statyczna funkcja Java, dostępna zarówno z Javy, jak i Kotlin as
Foo.a()
.Jeśli nie podoba mu się
Companion
nazwa, możesz także podać jawną nazwę dla obiektu towarzyszącego, który wygląda następująco:co pozwoli ci nazywać to z Kotlina w ten sam sposób, ale z języka java
Foo.Blah.a()
(który będzie działał również w Kotlinie).źródło
fun a(): Int { return 1 }
lub nawetfun a(): Int = 1
fun a() = 1
.Factory
to nazwa obiektu towarzyszącego - ale do czego można go użyć? Nie mam pojęcia, ale byłem zainteresowany, więc stworzyłem pytanie poświęcone temu tematowi : stackoverflow.com/q/45853459/221955 .Docs zaleca rozwiązanie większości potrzeb związanych z funkcjami statycznymi za pomocą funkcji na poziomie pakietu . Są po prostu zadeklarowane poza klasą w pliku kodu źródłowego. Pakiet pliku można określić na początku pliku za pomocą słowa kluczowego package.
Deklaracja
Stosowanie
Alternatywnie
Możesz teraz wywołać funkcję za pomocą:
lub jeśli nie używasz słowa kluczowego import:
Jeśli nie określisz pakietu, funkcja będzie dostępna z poziomu katalogu głównego.
Jeśli masz tylko doświadczenie z Javą, może się to wydawać trochę dziwne. Powodem jest to, że kotlin nie jest językiem ściśle obiektowym. Można powiedzieć, że obsługuje metody poza klasami.
Edycja: Dokonali edycji dokumentacji, aby nie zawierać już zdania na temat rekomendowania funkcji na poziomie pakietu. Jest to oryginał, o którym mowa powyżej.
źródło
class FooPackage
wszystkie właściwości i funkcje najwyższego poziomu i odpowiednio skieruje do nich wszystkie odniesienia. Więcej informacji z jetbrains.bar()
nie ma znaczenia nazwa pliku, możesz go nazwaćBarUtils.kt
lub cokolwiek, a następnie, jak mówi tekst, zaimportujesz go za pomocąimport <package name>.bar
A. Old Java Way:
Zadeklaruj a,
companion object
aby załączyć metodę / zmienną statycznąPosługiwać się :
B. Nowa droga Kotlin
Deklaruj bezpośrednio w pliku bez klasy w
.kt
pliku.Użyj
methods/variables
z ich nazwami . ( Po ich zaimportowaniu )Posługiwać się :
źródło
INSTANCE
słowo kluczowe, takie jak:Foo.INSTANCE.sayFoo()
static CLASS
nie tylkostatic methdos
. Ponieważ w przypadku obiektów towarzyszących nadal można utworzyć instancję klasy nadrzędnej.val
nie jest statyczny, to odpowiednikstatic final
w JavieUżyj obiektu do reprezentowania metody val / var /, aby uzyskać statyczną wartość. Możesz także użyć obiektu zamiast klasy singleton. Możesz użyć towarzysza, jeśli chcesz uczynić statycznym wewnątrz klasy
Jeśli chcesz zadzwonić z Java:
W Kotlin zignoruj INSTANCE.
źródło
To również działało dla mnie
z Kotlin
z Java
źródło
źródło
Musisz przekazać obiekt towarzyszący dla metody statycznej, ponieważ kotlin nie ma słowa kluczowego statycznego - Członkowie obiektu towarzyszącego można wywołać, używając po prostu nazwy klasy jako kwalifikatora:
źródło
Istnieją 2 sposoby zastosowania efektu statycznego w Kotlinie
Najpierw utwórz obiekt towarzyszący w klasie
Na przykład:
możesz wywołać tę funkcję jako
Innym sposobem, w jaki możemy użyć, jest utworzenie klasy obiektu
Happy Coding!
źródło
Test.Companion.isCheck(2)
) IDE pokazuje ostrzeżenia i powiedzCompanion reference is redundant
. Można go zredukować,Test.isCheck(2)
a zredukowana forma jest bardziej zbliżona do odpowiednika Java.Kotlin nie ma statycznego słowa kluczowego. Użyłeś tego dla java
i dla Kotlina
Zadzwoń po Javę
Zadzwoń po Kotlina
Myślę, że działa idealnie.
źródło
Chciałbym dodać coś do powyższych odpowiedzi.
Tak, możesz zdefiniować funkcje w plikach kodu źródłowego (poza klasą). Lepiej jest jednak zdefiniować funkcje statyczne w klasie za pomocą Companion Object, ponieważ można dodać więcej funkcji statycznych, korzystając z rozszerzeń Kotlin .
I możesz wywołać powyższą funkcję, tak jak wywołasz dowolną funkcję w obiekcie Companion.
źródło
Mimo że ma on już nieco ponad 2 lata i wiele wspaniałych odpowiedzi, widzę inne sposoby uzyskania „statycznych” pól Kotlina. Oto przykładowy przewodnik dla interakcji Kotlin-Java
static
:Odpowiedź Michaela Andersona zapewnia więcej głębi i na pewno należy się odwoływać do tego scenariusza.
Następny scenariusz obsługuje tworzenie pól statycznych w Kotlin, dzięki czemu Java nie musi wywoływać
KotlinClass.foo()
tych przypadków, w których nie chcesz funkcji statycznej.Jedną z wielkich zalet Kotlina jest możliwość tworzenia funkcji i zmiennych najwyższego poziomu. To sprawia, że warto tworzyć „bezklasowe” listy stałych pól i funkcji, które z kolei mogą być używane jako
static
funkcje / pola w Javie.Kolejną godną uwagi wzmianką, która może być używana w Javie jako pola „statyczne”, są
object
klasy Kotlin . Są to klasy singletonów o zerowym parametrze, które są tworzone leniwie przy pierwszym użyciu. Więcej informacji na ich temat można znaleźć tutaj: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarationsJednak, aby uzyskać dostęp do singletonu,
INSTANCE
tworzony jest specjalny obiekt, który jest tak samo niewygodny, jak się nimCompanion
zajmuje. Oto jak używać adnotacji, aby zapewnić czystystatic
wygląd w Javie:źródło
Krótko mówiąc, możesz użyć „obiektu towarzyszącego”, aby dostać się do statycznego świata Kotlin, takiego jak:
i aby zrobić stałe pole, użyj „const val” jak w kodzie. ale staraj się unikać klas statycznych, ponieważ utrudnia to testowanie jednostkowe przy użyciu Mockito !.
źródło
Dokładna konwersja metody statycznej Java na ekwiwalent kotlin byłaby taka. np. tutaj klasa util ma jedną metodę statyczną, która byłaby równoważna zarówno w java, jak i kotlin. Zastosowanie @JvmStatic jest ważne.
Kod Java:
Kod Kotlin:
źródło
Po prostu musisz utworzyć obiekt towarzyszący i umieścić w nim funkcję
Aby wywołać metodę z klasy kotlin:
lub Korzystanie z importu
Aby wywołać metodę z klasy Java:
lub dodając adnotację @JvmStatic do metody
lub oba, dodając adnotację @JvmStatic do metody i dokonując importu statycznego w Javie
źródło
W przypadku Java:
Odpowiednik kodu Kotlin:
Zatem odpowiednikiem metod statycznych Java jest klasa obiektowa w Kotlinie.
źródło
Dla systemu Android za pomocą ciągu od pojedynczego działania do wszystkich niezbędnych działań. Tak jak statyczny w java
public final static String TEA_NAME = "TEA_NAME";
Równoważne podejście w Kotlinie:
Kolejne działanie, w którym potrzebna jest wartość:
źródło
z wyjątkiem odpowiedzi Michaela Andersona, mam kodowanie z innymi dwoma sposobami w moim projekcie.
Pierwszy:
możesz białą zmienną na jedną klasę. utworzył plik Kotlin o nazwie Const
Możesz go używać w kodzie kotlin i java
Druga:
Możesz użyć funkcji rozszerzenia Kotlin, która
utworzyła plik Kotlin o nazwie Ext, poniżej kodu jest cały kod w pliku Ext
Możesz go użyć w kodzie kotlin
Możesz go użyć w kodzie Java
źródło
Zapisz je bezpośrednio do plików.
W Javie (brzydka):
W Kotlinie:
Te dwa fragmenty kodów są równoważone po kompilacji (nawet nazwa skompilowanego pliku
file:JvmName
służy do kontrolowania nazwy skompilowanego pliku, który należy umieścić tuż przed deklaracją nazwy pakietu).źródło
Użyj
@JVMStatic
adnotacjiźródło
Niech masz klasowego ucznia . I masz jedną metodę statyczną getUniversityName () i jedno pole statyczne o nazwie totalStudent .
Powinieneś zadeklarować blok obiektów towarzyszących w swojej klasie.
Wtedy twoja klasa wygląda
Następnie możesz użyć tych statycznych metod i pól w ten sposób.
źródło
W kotlin nie ma statycznego słowa kluczowego. kotlin docs zaleca korzystanie z funkcji na poziomie pakietu, jeśli chcesz stosować DRY. Utwórz plik z rozszerzeniem .kt i umieść w nim swoją metodę.
po kompilacji m będzie miał podpis publicznej ostatecznej nieważności
i
☺
źródło
Funkcję statyczną można osiągnąć w Kotlin dzięki obiektom towarzyszącym
Obiekt towarzyszący nie może zostać zadeklarowany poza klasą.
Członkowie obiektu towarzyszącego można wywoływać, używając po prostu nazwy klasy jako kwalifikatora:
Wynik:
źródło
Wszystkie elementy statyczne i funkcje powinny znajdować się w bloku pomocniczym
źródło
Wiele osób wspomina o obiektach towarzyszących, co jest poprawne. Ale dla pewności możesz użyć dowolnego obiektu (używając słowa kluczowego object, a nie klasy), tj.
Użyj go tak jak każdej metody statycznej w Javie:
Ten rodzaj wzorca jest jednak trochę bezużyteczny w Kotlinie, jedną z jego zalet jest to, że pozbywa się potrzeby klas wypełnionych metodami statycznymi. Bardziej właściwe jest korzystanie z funkcji globalnych, rozszerzeń i / lub lokalnych, w zależności od przypadku użycia. Tam, gdzie pracuję, często definiujemy globalne funkcje rozszerzeń w osobnym, płaskim pliku z konwencją nazewnictwa: [nazwa_klasy] Extensions.kt tj. FooExtensions.kt. Ale częściej piszemy funkcje tam, gdzie są potrzebne w swojej klasie operacyjnej lub obiekcie.
źródło
W Javie możemy pisać poniżej
W Kotlinie możemy pisać poniżej
Towarzysz jest używany jako statyczny w Kotlinie.
źródło
Dostawca dokumentów kotlin ma na to trzy sposoby, pierwszy to zdefiniowanie funkcji w pakiecie, bez klasy:
drugim jest użycie adnotacji @JvmStatic:
a trzeci to użyj obiektu towarzyszącego:
źródło
Jeśli potrzebujesz funkcji lub właściwości do powiązania z klasą, a nie z jej instancjami, możesz zadeklarować ją w obiekcie towarzyszącym:
Obiekt towarzyszący jest singletonem, a do jego elementów można uzyskać bezpośredni dostęp poprzez nazwę klasy zawierającej
źródło
Możesz użyć przedmiotów towarzyszących - kotlinlang
Które można pokazać, tworząc najpierw ten interfejs
Następnie musimy stworzyć funkcję wewnątrz tego interfejsu:
Potem potrzebujemy zajęć:
wewnątrz tej klasy potrzebujemy obiektu towarzyszącego w tej klasie:
wewnątrz tego obiektu towarzyszącego potrzebujemy tej starej
SomeFunc
funkcji, ale musimy go przejechać:Wreszcie poniżej całej tej pracy, Potrzebujemy czegoś do zasilania tej funkcji statycznej, Potrzebujemy zmiennej:
źródło