Non esiste una static
parola chiave in Kotlin.
Qual è il modo migliore per rappresentare un static
metodo Java in Kotlin?
Non esiste una static
parola chiave in Kotlin.
Qual è il modo migliore per rappresentare un static
metodo Java in Kotlin?
Risposte:
Posizionare la funzione nell '"oggetto compagno".
Quindi il codice java in questo modo:
class Foo {
public static int a() { return 1; }
}
diventerà
class Foo {
companion object {
fun a() : Int = 1
}
}
Puoi quindi usarlo dal codice Kotlin come
Foo.a();
Ma dal codice Java, dovresti chiamarlo come
Foo.Companion.a();
(Che funziona anche dall'interno di Kotlin.)
Se non ti piace dover specificare il Companion
bit, puoi aggiungere @JvmStatic
un'annotazione o denominare la tua classe compagno.
Dai documenti :
Companion Objects
Una dichiarazione di oggetto all'interno di una classe può essere contrassegnata con la parola chiave companion:
class MyClass { companion object Factory { fun create(): MyClass = MyClass() } }
I membri dell'oggetto associato possono essere chiamati semplicemente usando il nome della classe come qualificatore:
val instance = MyClass.create()
...
Tuttavia, su JVM è possibile generare membri di oggetti companion come metodi e campi statici reali, se si utilizza l'
@JvmStatic
annotazione. Vedi la sezione di interoperabilità Java per maggiori dettagli.
L'aggiunta @JvmStatic
dell'annotazione è simile a questa
class Foo {
companion object {
@JvmStatic
fun a() : Int = 1;
}
}
e quindi esisterà come una vera funzione statica Java, accessibile sia da Java che da Kotlin Foo.a()
.
Se non è stato semplicemente apprezzato il Companion
nome, puoi anche fornire un nome esplicito per l'oggetto associato:
class Foo {
companion object Blah {
fun a() : Int = 1;
}
}
che ti permetterà di chiamarlo da Kotlin allo stesso modo, ma da java like Foo.Blah.a()
(che funzionerà anche in Kotlin).
fun a(): Int { return 1 }
o addiritturafun a(): Int = 1
fun a() = 1
.
Factory
è il nome dell'oggetto associato - ma a cosa può servire? Non ne ho idea, ma ero interessato, quindi ho creato una domanda dedicata a questo: stackoverflow.com/q/45853459/221955 .
Docs consiglia di risolvere la maggior parte delle esigenze di funzioni statiche con funzioni a livello di pacchetto . Sono semplicemente dichiarati al di fuori di una classe in un file di codice sorgente. Il pacchetto di un file può essere specificato all'inizio di un file con la parola chiave pacchetto.
Dichiarazione
package foo
fun bar() = {}
uso
import foo.bar
In alternativa
import foo.*
Ora puoi chiamare la funzione con:
bar()
o se non si utilizza la parola chiave import:
foo.bar()
Se non si specifica il pacchetto, la funzione sarà accessibile dalla radice.
Se hai solo esperienza con Java, questo potrebbe sembrare un po 'strano. Il motivo è che kotlin non è un linguaggio strettamente orientato agli oggetti. Si potrebbe dire che supporta metodi al di fuori delle classi.
Modifica: hanno modificato la documentazione per non includere più la frase relativa alla raccomandazione di funzioni a livello di pacchetto. Questo è l'originale di cui sopra.
class FooPackage
con tutte le proprietà e le funzioni di livello superiore e instraderebbe tutti i riferimenti ad essi in modo appropriato. Maggiori informazioni da jetbrains.
bar()
non importa il nome del file, è possibile nominarlo BarUtils.kt
o altro, quindi come dice il testo lo si importerà conimport <package name>.bar
A. Vecchio modo Java:
Dichiarare a companion object
di racchiudere un metodo / una variabile statici
class Foo{
companion object {
fun foo() = println("Foo")
val bar ="bar"
}
}
Uso :
Foo.foo() // Outputs Foo
println(Foo.bar) // Outputs bar
B. Nuova via di Kotlin
Dichiarare direttamente sul file senza classe su un .kt
file.
fun foo() = println("Foo")
val bar ="bar"
Usa il methods/variables
con i loro nomi . ( Dopo averli importati )
Uso :
foo() // Outputs Foo
println(bar) // Outputs bar
INSTANCE
parola chiave, in questo modo:Foo.INSTANCE.sayFoo()
static CLASS
non solo static methdos
. Perché con gli oggetti companion è ancora possibile creare un'istanza della classe genitore.
val
non è statico, è equivalente a static final
in Java
Utilizzare object per rappresentare val / var / method per rendere statico. È possibile utilizzare anche l'oggetto anziché la classe singleton. Puoi usare il compagno se vuoi rendere statico all'interno di una classe
object Abc{
fun sum(a: Int, b: Int): Int = a + b
}
Se è necessario chiamarlo da Java:
int z = Abc.INSTANCE.sum(x,y);
A Kotlin, ignora ISTANZA.
object objectName {
fun funName() {
}
}
Devi passare l'oggetto compagno per il metodo statico perché kotlin non ha una parola chiave statica - I membri dell'oggetto compagno possono essere chiamati semplicemente usando il nome della classe come qualificatore:
package xxx
class ClassName {
companion object {
fun helloWord(str: String): String {
return stringValue
}
}
}
Esistono 2 modi per applicare statica in Kotlin
Per prima cosa crea un oggetto compagno sotto classe
Ad esempio:
class Test{
companion object{
fun isCheck(a:Int):Boolean{
if(a==0) true else false
}
}
}
puoi chiamare questa funzione come
Test.Companion.isCheck(2)
Un altro modo in cui possiamo usare è creare una classe di oggetti
object Test{
fun isCheck(a:Int):Boolean{
if(a==0) true else false
}
}
Buona programmazione!
Test.Companion.isCheck(2)
) IDE mostra avvertimenti e dire Companion reference is redundant
. Può essere ridotto a Test.isCheck(2)
e la forma ridotta è più vicina all'equivalente Java.
Kotlin non ha parole chiave statiche. L'hai usato per Java
class AppHelper {
public static int getAge() {
return 30;
}
}
e per Kotlin
class AppHelper {
companion object {
fun getAge() : Int = 30
}
}
Chiama per Java
AppHelper.getAge();
Chiama per Kotlin
AppHelper.Companion.getAge();
Penso che funzioni perfettamente.
Vorrei aggiungere qualcosa alle risposte sopra.
Sì, è possibile definire le funzioni nei file di codice sorgente (classe esterna). Ma è meglio se si definiscono funzioni statiche all'interno della classe utilizzando Companion Object perché è possibile aggiungere più funzioni statiche sfruttando le estensioni di Kotlin .
class MyClass {
companion object {
//define static functions here
}
}
//Adding new static function
fun MyClass.Companion.newStaticFunction() {
// ...
}
E puoi chiamare la funzione sopra definita poiché chiamerai qualsiasi funzione all'interno di Companion Object.
Anche se ormai ha poco più di 2 anni e ha avuto molte ottime risposte, sto vedendo che mancano alcuni altri modi per ottenere campi Kotlin "statici". Ecco una guida di esempio per l' static
interoperabilità Kotlin-Java :
Scenario 1: creazione di un metodo statico in Kotlin per 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 } }
Giava
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); } }
La risposta di Michael Anderson fornisce più profondità di questa e dovrebbe sicuramente essere referenziata per questo scenario.
Questo scenario successivo gestisce la creazione di campi statici in Kotlin in modo che Java non debba continuare a chiamare KotlinClass.foo()
quei casi in cui non si desidera una funzione statica.
Scenario 2: creazione di una variabile statica in Kotlin per 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 } }
Giava
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); } }
Una delle grandi caratteristiche di Kotlin è che puoi creare funzioni e variabili di livello superiore. Ciò rende piacevole la creazione di elenchi "senza classi" di campi e funzioni costanti, che a loro volta possono essere utilizzati come static
funzioni / campi in Java.
Scenario 3: accesso ai campi e alle funzioni di livello superiore in Kotlin da 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 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!") }
Giava
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); } }
Un'altra menzione notevole che può essere usata in Java come campi "statici" sono le object
classi di Kotlin . Queste sono classi singleton a zero parametri che sono istanziate pigramente al primo utilizzo. Maggiori informazioni su di essi sono disponibili qui: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations
Tuttavia, per accedere al singleton, INSTANCE
viene creato un oggetto speciale , che è altrettanto ingombrante da gestire come lo Companion
è. Ecco come utilizzare le annotazioni per conferire un static
aspetto pulito in Java:
Scenario 4: utilizzo delle
object
classiKotlin
@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'?" }
Giava
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); } }
Per farla breve potresti usare "oggetto compagno" per entrare nel mondo statico di Kotlin come:
companion object {
const val TAG = "tHomeFragment"
fun newInstance() = HomeFragment()
}
e per fare un campo costante usa "const val" come nel codice. ma cerca di evitare le classi statiche in quanto sta creando difficoltà nei test unitari usando Mockito !.
L'esatta conversione del metodo statico java in equivalente kotlin sarebbe così. es. Qui la classe util ha un metodo statico che sarebbe equivalente sia in java che in kotlin. L'uso di @JvmStatic è importante.
Codice Java:
class Util{
public static String capitalize(String text){
return text.toUpperCase();}
}
Codice Kotlin:
class Util {
companion object {
@JvmStatic
fun capitalize(text:String): String {
return text.toUpperCase()
}
}
}
Devi semplicemente creare un oggetto associato e inserirvi la funzione
class UtilClass {
companion object {
// @JvmStatic
fun repeatIt5Times(str: String): String = str.repeat(5)
}
}
Per invocare il metodo da una classe kotlin:
class KotlinClass{
fun main(args : Array<String>) {
UtilClass.repeatIt5Times("Hello")
}
}
o Utilizzo dell'importazione
import Packagename.UtilClass.Companion.repeatIt5Times
class KotlinClass{
fun main(args : Array<String>) {
repeatIt5Times("Hello")
}
}
Per invocare il metodo da una classe java:
class JavaClass{
public static void main(String [] args){
UtilClass.Companion.repeatIt5Times("Hello");
}
}
o aggiungendo l'annotazione @JvmStatic al metodo
class JavaClass{
public static void main(String [] args){
UtilClass.repeatIt5Times("Hello")
}
}
o entrambi aggiungendo l'annotazione @JvmStatic al metodo ed eseguendo l'importazione statica in java
import static Packagename.UtilClass.repeatIt5Times
class JavaClass{
public static void main(String [] args){
repeatIt5Times("Hello")
}
}
Per Java:
public class Constants {
public static final long MAX_CLICK_INTERVAL = 1000;}
Codice Kotlin equivalente:
object Constants {
const val MAX_CLICK_INTERVAL: Long = 1000}
Quindi per l'equivalente dei metodi statici Java è la classe di oggetti in Kotlin.
Per Android utilizzando una stringa da una singola attività a tutte le attività necessarie. Proprio come statico in Java
public final static String TEA_NAME = "TEA_NAME";
Approccio equivalente a 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)
}
}
Un'altra attività in cui è necessario un valore:
val teaName = MainActivity.TEA_NAME
ad eccezione della risposta di Michael Anderson, nel mio progetto ho programmato altri due modi.
puoi bianco tutte le variabili in una classe. creato un file kotlin chiamato Const
object Const {
const val FIRST_NAME_1 = "just"
const val LAST_NAME_1 = "YuMu"
}
Puoi usarlo nel codice kotlin e java
Log.d("stackoverflow", Const.FIRST_NAME_1)
Puoi usare la funzione di estensione di Kotlin
creata un file kotlin chiamato Ext , sotto il codice è il codice tutto nel file Ext
package pro.just.yumu
/**
* Created by lpf on 2020-03-18.
*/
const val FIRST_NAME = "just"
const val LAST_NAME = "YuMu"
Puoi usarlo nel codice di kotlin
Log.d("stackoverflow", FIRST_NAME)
Puoi usarlo nel codice java
Log.d("stackoverflow", ExtKt.FIRST_NAME);
Scrivili direttamente nei file.
In Java (brutto):
package xxx;
class XxxUtils {
public static final Yyy xxx(Xxx xxx) { return xxx.xxx(); }
}
A Kotlin:
@file:JvmName("XxxUtils")
package xxx
fun xxx(xxx: Xxx): Yyy = xxx.xxx()
Quei due pezzi di codice vengono eguagliati dopo la compilazione (anche il nome del file compilato, file:JvmName
viene utilizzato per controllare il nome del file compilato, che dovrebbe essere inserito appena prima della dichiarazione del nome del pacchetto).
Usa @JVMStatic
annotazione
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)
}
}
}
Lascia, hai uno studente di classe . E hai un metodo statico getUniversityName () e un campo statico chiamato totalStudent .
Dovresti dichiarare il blocco di oggetti companion all'interno della tua classe.
companion object {
// define static method & field here.
}
Quindi la tua classe sembra
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
}
}
Quindi puoi usare questi metodi e campi statici in questo modo.
println("University : " + Student.getUniversityName() + ", Total Student: " + Student.totalStudent)
// Output:
// University : MBSTU, Total Student: 30
Non esiste una parola chiave statica in kotlin. kotlin docs consiglia di utilizzare le funzioni a livello di pacchetto se si desidera seguire DRY. Crea un file con estensione .kt e inserisci il tuo metodo.
package p
fun m(){
//fun body
}
dopo la compilazione m avrà una firma del vuoto finale statico pubblico
e
import p.m
☺
Puoi ottenere la funzionalità statica in Kotlin da Companion Objects
Un oggetto associato non può essere dichiarato al di fuori della classe.
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"
}
}
}
I membri dell'oggetto associato possono essere chiamati semplicemente usando il nome della classe come qualificatore:
Produzione:
MyClass.staticField // This is an example of static field Object Decleration
MyClass.getStaticFunction() : // This is an example of static function for Object Decleration
Molte persone menzionano oggetti associati, il che è corretto. Ma, solo per quello che sai, puoi anche usare qualsiasi tipo di oggetto (usando la parola chiave object, non class) cioè
object StringUtils {
fun toUpper(s: String) : String { ... }
}
Usalo proprio come qualsiasi metodo statico in Java:
StringUtils.toUpper("foobar")
Quel tipo di schema è in qualche modo inutile in Kotlin, uno dei suoi punti di forza è che si sbarazza della necessità di classi piene di metodi statici. È più appropriato utilizzare invece funzioni globali, di estensione e / o locali, a seconda del caso d'uso. Dove lavoro spesso definiamo le funzioni di estensione globale in un file separato e piatto con la convenzione di denominazione: [className] Extensions.kt cioè FooExtensions.kt. Ma più tipicamente scriviamo funzioni dove sono necessarie all'interno della loro classe operativa o oggetto.
In Java, possiamo scrivere in basso
class MyClass {
public static int myMethod() {
return 1;
}
}
In Kotlin, possiamo scrivere in basso
class MyClass {
companion object {
fun myMethod() : Int = 1
}
}
un compagno viene usato come statico in Kotlin.
Il fornitore di documenti kotlin ha tre modi per farlo, il primo è definire la funzione nel pacchetto, senza classe:
package com.example
fun f() = 1
il secondo è usare l'annotazione @JvmStatic:
package com.example
class A{
@JvmStatic
fun f() = 1
}
e il terzo è usare l'oggetto compagno:
package com.example
clss A{
companion object{
fun f() = 1
}
}
Se è necessaria una funzione o una proprietà da associare a una classe anziché a istanze di essa, è possibile dichiararla all'interno di un oggetto compagno:
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
}
}
}
L'oggetto associato è un singleton e ai suoi membri è possibile accedere direttamente tramite il nome della classe contenente
val car = Car.makeCar(150)
println(Car.Factory.cars.size)
Puoi usare Companion Objects - kotlinlang
Che può essere mostrato creando prima quell'interfaccia
interface I<T> {
}
Quindi dobbiamo fare una funzione all'interno di quella interfaccia:
fun SomeFunc(): T
Quindi dopo, abbiamo bisogno di una classe:
class SomeClass {}
all'interno di quella classe abbiamo bisogno di un oggetto associato all'interno di quella classe:
companion object : I<SomeClass> {}
all'interno di quel Companion Object abbiamo bisogno di quella vecchia SomeFunc
funzione, ma dobbiamo superarla:
override fun SomeFunc(): SomeClass = SomeClass()
Infine sotto tutto quel lavoro, abbiamo bisogno di qualcosa per alimentare quella funzione statica, abbiamo bisogno di una variabile:
var e:I<SomeClass> = SomeClass()