web-dev-qa-db-fra.com

Quel est l'équivalent de Java méthodes statiques dans Kotlin?

Il n'y a pas de mot clé static dans Kotlin.

Quel est le meilleur moyen de représenter une méthode static Java dans Kotlin?

493
pdeva

Vous placez la fonction dans "l'objet compagnon".

Donc, le code Java ressemble à ceci:

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

va devenir

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

Vous pouvez ensuite l'utiliser depuis le code Kotlin en tant que

Foo.a();

Mais à partir du code Java, vous devez l’appeler en tant que

Foo.Companion.a();

(Ce qui fonctionne aussi depuis Kotlin.)

Si vous n'aimez pas avoir à spécifier le bit Companion, vous pouvez ajouter une annotation @JvmStatic ou nommer votre classe d'accompagnement.

De la docs :

Objets Compagnon

Une déclaration d'objet à l'intérieur d'une classe peut être marquée avec le mot clé compagnon:

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

Les membres de l'objet compagnon peuvent être appelés en utilisant simplement le nom de la classe comme qualificatif:

val instance = MyClass.create()

...

Toutefois, sur la machine virtuelle Java, vous pouvez générer des membres d'objets compagnons sous forme de méthodes et de champs statiques réels, si vous utilisez l'annotation @JvmStatic. Voir la section sur l'interopérabilité Java pour plus de détails.

L'ajout de l'annotation @JvmStatic ressemble à ceci

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

et alors elle existera comme une vraie fonction statique Java, accessible à partir de Java et de Kotlin en tant que Foo.a().

Si le nom Companion ne vous plaît pas, vous pouvez également fournir un nom explicite pour l'objet compagnon qui ressemble à ceci:

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

ce qui vous permettra de l'appeler de Kotlin de la même manière, mais de Java comme Foo.Blah.a() (qui fonctionnera également en Kotlin).

704
Michael Anderson

Docs recommande de résoudre la plupart des besoins en fonctions statiques avec des fonctions au niveau du package . Ils sont simplement déclarés en dehors d'une classe dans un fichier de code source. Le package d'un fichier peut être spécifié au début d'un fichier avec le mot clé package.

Déclaration

package foo

fun bar() = {}

Utilisation

import foo.bar

Alternativement

import foo.*

Vous pouvez maintenant appeler la fonction avec:

bar()

ou si vous n'utilisez pas le mot clé import:

foo.bar()

Si vous ne spécifiez pas le package, la fonction sera accessible à partir de la racine.

Si vous n’avez qu’une expérience de Java, cela peut sembler un peu étrange. La raison en est que kotlin n'est pas un langage strictement orienté objet. Vous pourriez dire que cela prend en charge les méthodes en dehors des classes.

111
Henrik F.

A. Old Java Way:

  1. Déclarez un companion object pour entourer un méthode/variable

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

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


B. Nouvelle voie Kotlin

  1. Déclarez directement sur le fichier sans classe sur un fichier .kt.

    fun foo() = println("Foo")
    val bar ="bar"
    
  2. Utilisez les methods/variables avec leurs noms. (Après les avoir importés)

    Utilisation :

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

24
erluxman

Utilisez object pour représenter val/var/method afin de rendre statique. Vous pouvez également utiliser object au lieu de singleton. Vous pouvez utiliser compagnon si vous voulez rendre statique à l'intérieur d'une classe

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

Si vous avez besoin de l'appeler depuis Java:

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

Dans Kotlin, ignorez INSTANCE.

19
Asharali V U

Cela a également fonctionné pour moi

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

de Kotlin

Bell.ring()

de Java

Bell.ring()
7
Samuel

Vous devez transmettre un objet compagnon pour une méthode statique car kotlin n’a pas de mot clé statique. Vous pouvez appeler les membres de l’objet compagnon en utilisant simplement le nom de la classe comme qualificatif:

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

    }
}
5
Umesh Maharjan

Vous pouvez appliquer du statique dans Kotlin de deux façons.

Commencez par créer un objet compagnon dans la classe

Pour ex:

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

vous pouvez appeler cette fonction

Test.Companion.isCheck(2)

Nous pouvons aussi utiliser une classe d'objet

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

Bon codage!

4
Android Geek

Kotlin n'a pas de mot clé statique. Vous avez utilisé cela pour Java

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

et pour Kotlin

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

Appel à Java

AppHelper.getAge();

Appel à Kotlin

AppHelper.Companion.getAge();

Je pense que cela fonctionne parfaitement.

3
Shohel Rana

Pour faire court, vous pouvez utiliser "objet compagnon" pour entrer dans le monde statique de Kotlin comme:

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

et pour faire un champ constant, utilisez "const val" comme dans le code. mais essayez d’éviter les classes statiques car cela pose des difficultés lors des tests unitaires avec Mockito !.

3
CodeRanger

Je voudrais ajouter quelque chose aux réponses ci-dessus.

Oui, vous pouvez définir des fonctions dans des fichiers de code source (en dehors de la classe). Mais il est préférable de définir des fonctions statiques dans la classe à l'aide de objet compagnon, car vous pouvez ajouter davantage de fonctions statiques en utilisant les éléments Extensions Kotlin.

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

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

Et vous pouvez appeler une fonction définie ci-dessus, comme vous appelez n'importe quelle fonction dans l'objet Compagnon.

3
SVB-knowmywork

Même si cela fait un peu plus de 2 ans maintenant et que nous avons eu d'excellentes réponses, je vois d'autres moyens de supprimer les champs de Kotlin "statiques". Voici un exemple de guide pour Kotlin-Java static interop:

Scénario 1: Création d'une méthode statique dans Kotlin pour 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);
    }
}

La réponse de Michael Anderson fournit plus de profondeur que cela et devrait certainement être référencée pour ce scénario.


Ce scénario suivant traite de la création de champs statiques dans Kotlin afin que Java ne soit pas obligé de continuer à appeler KotlinClass.foo() dans les cas où vous ne souhaitez pas de fonction statique.

Scénario 2: Création d'une variable statique dans Kotlin pour 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);
    }
}

Une des fonctionnalités intéressantes de Kotlin est que vous pouvez créer des fonctions et des variables de niveau supérieur. Cela facilite la création de listes "sans classes" de champs et fonctions constants, qui peuvent à leur tour être utilisés en tant que fonctions/champs static en Java.

Scénario 3: Accès aux champs et fonctions de niveau supérieur dans Kotlin à partir de 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!")
}

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

Une autre mention notable utilisable dans Java en tant que champs "statiques" est Kotlin object. Ce sont des classes de singleton à zéro paramètre instanciées paresseusement lors de la première utilisation. Plus d'informations à leur sujet peuvent être trouvées ici: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations

Cependant, pour accéder au singleton, un objet INSTANCE spécial est créé, ce qui est aussi difficile à gérer que Companion. Voici comment utiliser des annotations pour lui donner cette sensation propre static en Java:

Scénario 4: Utilisation de object classes

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

Vous devez simplement créer un objet compagnon et y placer la fonction.

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

Pour appeler la méthode depuis une classe kotlin:

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

ou en utilisant import

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

Pour appeler la méthode à partir d'une classe Java:

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

ou en ajoutant une annotation @JvmStatic à la méthode

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

ou les deux en ajoutant une annotation @JvmStatic à la méthode et en effectuant une importation statique en Java

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

Les objets compagnons sont l'alternative du mot clé statique Java et vous pouvez créer une classe ou une méthode statique en les déclarant objets compagnons.
Vous n’avez pas besoin de qualifier les objets compagnons avec le nom de la classe, même si vous les appelez depuis la même classe.

Par exemple:

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

Vous pouvez utiliser des objets autres qu'un objet compagnon

object Utils {
    fun someFunction()
}

Cela ressemblera donc à l'appel de la méthode.

Utils.someFunction()
2
dr3k

faire un objet compagnon et marquer la méthode avec l'annotation jvmstatic

2
user9092442

La conversion exacte de la méthode statique Java en équivalent kotlin serait la suivante. par exemple. Ici, la classe util a une méthode statique qui serait équivalente à la fois Java et kotlin. L'utilisation de @ JvmStatic est importante.

 //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

Utilisez la fonction dans "objet compagnon ou objet nommé".

Voir exemple d'objet compagnon:

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

Voir l'exemple d'objet nommé

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

Vous pouvez accéder en utilisant

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

Ecrivez-les directement dans des fichiers.

Dans Java (moche):

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

À Kotlin:

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

Ces deux morceaux de code sont égaux après la compilation (même le nom de fichier compilé, le file:JvmName est utilisé pour contrôler le nom du fichier compilé, qui doit être placé juste avant la déclaration du nom du paquet).

1
ice1000

Laissez, vous avez une classe étudiant. Et vous avez un statique méthode getUniversityName () & one statique champ appelé totalStudent.

Vous devriez déclarer objet compagnon bloquer à l'intérieur de votre classe.

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

Ensuite, votre classe ressemble à

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

Ensuite, vous pouvez utiliser ces méthodes et champs statiques comme ceci.

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

Pour Java:

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

Code Kotlin équivalent:

object  Constants {
const val MAX_CLICK_INTERVAL: Long = 1000}

Donc, pour l'équivalent de Java méthodes statiques, il s'agit de la classe d'objets en Kotlin.

1
Paulami Biswas

Utiliser @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

Tous les membres et fonctions statiques doivent être à l'intérieur du bloc compagnon

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

    fun staticMethod() {
    }
  }
0
Rahul

En Java, on peut écrire ci-dessous

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

En Kotlin, nous pouvons écrire ci-dessous

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

un compagnon est utilisé en statique dans Kotlin.

0
Nikhil Katekhaye

Beaucoup de gens mentionnent des objets compagnon, ce qui est correct. Mais, pour votre information, vous pouvez également utiliser n’importe quel type d’objet (en utilisant le mot-clé object, pas la classe), c.-à-d.,

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

Utilisez-le comme n'importe quelle méthode statique en Java:

StringUtils.toUpper("foobar")

Ce type de modèle est en quelque sorte inutile en Kotlin, mais l’un de ses points forts est qu’il supprime le besoin de classes remplies de méthodes statiques. Il est plus approprié d'utiliser des fonctions globales, d'extension et/ou locales, selon votre cas d'utilisation. Là où je travaille, nous définissons souvent des fonctions d'extension globales dans un fichier plat séparé avec la convention d'appellation: [className] Extensions.kt, c'est-à-dire FooExtensions.kt. Mais plus généralement, nous écrivons des fonctions là où elles sont nécessaires dans leur classe d'opération ou leur objet.

0
pranalli

Vous pouvez obtenir la fonctionnalité statique dans Kotlin avec Objets associés

  • L'ajout de compagnon à la déclaration d'objet permet d'ajouter la fonctionnalité statique à un objet même si le concept statique réel n'existe pas dans Kotlin.
  • Un objet compagnon peut également accéder à tous les membres de la classe, y compris les constructeurs privés.
  • Un objet compagnon est initialisé lorsque la classe est instanciée.
  • Un objet compagnon ne peut pas être déclaré en dehors de la 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"
            }
    
        }
    }
    

Les membres de l'objet compagnon peuvent être appelés en utilisant simplement le nom de la classe comme qualificatif:

Sortie:

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

Le fournisseur de documents kotlin dispose de trois méthodes pour le faire. La première est de définir une fonction dans un package, sans classe:

package com.example

fun f() = 1

la seconde est d'utiliser l'annotation @JvmStatic:

package com.example

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

et le troisième est utiliser un objet compagnon:

package com.example

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

Le code Java se présente comme ci-dessous:

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

deviendra comme ci-dessous dans kotlin:

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

Cependant, en utilisant l'annotation @JvmStatic sur la machine virtuelle Java, les membres des objets compagnon peuvent être générés sous forme de méthodes et de champs statiques réels.

0
hetsgandhi