简体   繁体   English

Kotlin 中 Java 静态方法的等价物是什么?

[英]What is the equivalent of Java static methods in Kotlin?

There is no static keyword in Kotlin. Kotlin 中没有static关键字。

What is the best way to represent a static Java method in Kotlin?在 Kotlin 中表示static Java 方法的最佳方式是什么?

You place the function in the "companion object".您将函数放置在“伴随对象”中。

So the java code like this:所以java代码是这样的:

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

will become将成为

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

You can then use it from inside Kotlin code as然后您可以在 Kotlin 代码中使用它作为

Foo.a();

But from within Java code, you would need to call it as但是在 Java 代码中,您需要将其称为

Foo.Companion.a();

(Which also works from within Kotlin.) (这也适用于 Kotlin 内部。)

If you don't like having to specify the Companion bit you can either add a @JvmStatic annotation or name your companion class.如果您不想指定Companion位,您可以添加@JvmStatic注释或命名您的伴生类。

From the docs :文档

Companion Objects伴随对象

An object declaration inside a class can be marked with the companion keyword:类中的对象声明可以用companion关键字标记:

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

Members of the companion object can be called by using simply the class name as the qualifier:可以通过简单地使用类名作为限定符来调用伴生对象的成员:

 val instance = MyClass.create()

... ...

However, on the JVM you can have members of companion objects generated as real static methods and fields, if you use the @JvmStatic annotation.但是,在 JVM 上,如果您使用@JvmStatic注释,您可以将伴随对象的成员生成为真正的静态方法和字段。 See the Java interoperability section for more details.有关更多详细信息,请参阅Java 互操作性部分。

Adding the @JvmStatic annotation looks like this添加@JvmStatic注释看起来像这样

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

and then it will exist as a real Java static function, accessible from both Java and Kotlin as Foo.a() .然后它将作为真正的 Java 静态函数存在,可以从 Java 和 Kotlin 以Foo.a()

If it is just disliked for the Companion name, then you can also provide an explicit name for the companion object looks like this:如果只是不喜欢Companion名称,那么您还可以为伴生对象提供一个显式名称,如下所示:

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

which will let you call it from Kotlin in the same way, but from java like Foo.Blah.a() (which will also work in Kotlin).这将让您以相同的方式从 Kotlin 调用它,但是从像Foo.Blah.a()这样的 Java 调用它(它也可以在 Kotlin 中工作)。

Docs recommends to solve most of the needs for static functions with package-level functions . Docs建议使用包级函数来解决大部分静态函数的需求。 They are simply declared outside a class in a source code file.它们只是在源代码文件中的类之外声明。 The package of a file can be specified at the beginning of a file with the package keyword.文件的包可以在文件的开头用 package 关键字指定。

Declaration声明

package foo

fun bar() = {}

Usage用法

import foo.bar

Alternatively或者

import foo.*

You can now call the function with:您现在可以使用以下命令调用该函数:

bar()

or if you do not use the import keyword:或者如果您不使用 import 关键字:

foo.bar()

If you do not specify the package the function will be accessible from the root.如果您不指定包,则可以从根访问该函数。

If you only have experience with java, this might seem a little strange.如果您只有 Java 经验,这可能看起来有点奇怪。 The reason is that kotlin is not a strictly object-oriented language.原因是 kotlin 不是严格的面向对象语言。 You could say it supports methods outside of classes.你可以说它支持类之外的方法。

Edit: They have edited the documentation to no longer include the sentence about recommending package level functions.编辑:他们编辑了文档,不再包含关于推荐包级功能的句子。 This is the original that was referred to above. 是上面提到的原文。

A. Old Java Way : A. 旧的 Java 方式:

  1. Declare a companion object to enclose a static method / variable声明一个companion object来包含一个静态方法/变量

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

     Foo.foo() // Outputs Foo println(Foo.bar) // Outputs bar


B. New Kotlin way B. 新的 Kotlin 方式

  1. Declare directly on file without class on a .kt file.直接在文件上声明.kt文件上没有类

     fun foo() = println("Foo") val bar ="bar"
  2. Use the methods/variables with their names .使用methods/variables及其名称 ( After importing them ) 导入后

    Use :使用:

     foo() // Outputs Foo println(bar) // Outputs bar

Use object to represent val/var/method to make static.使用object表示 val/var/method 使其成为静态。 You can use object instead of singleton class also.您也可以使用 object 而不是单例类。 You can use companion if you wanted to make static inside of a class如果您想在类中静态化,可以使用伴侣

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

If you need to call it from Java:如果您需要从 Java 调用它:

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

In Kotlin, ignore INSTANCE.在 Kotlin 中,忽略 INSTANCE。

This also worked for me这也对我有用

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

from Kotlin来自科特林

Bell.ring()

from Java来自爪哇

Bell.ring()
object objectName {
    fun funName() {

    }
}

Even though this is a bit over 2 years old now, and had plenty of great answers, I am seeing some other ways of getting "static" Kotlin fields are missing.尽管这已经有 2 年多的历史了,并且有很多很好的答案,但我发现缺少其他一些获取“静态”Kotlin 字段的方法。 Here is an example guide for Kotlin-Java static interop:以下是 Kotlin-Java static互操作的示例指南:

Scenario 1: Creating a static method in Kotlin for Java场景 1:在 Kotlin for 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); } }

Michael Anderson's answer provides more depth than this, and should definitely be referenced for this scenario.迈克尔安德森的回答提供了比这更深入的内容,并且绝对应该在这种情况下被引用。


This next scenario handles creating static fields in Kotlin so that Java doesn't have to keep calling KotlinClass.foo() for those cases where you don't want a static function.下一个场景处理在 Kotlin 中创建静态字段,这样 Java 就不必在不需要静态函数的情况下继续调用KotlinClass.foo()

Scenario 2: Creating a static variable in Kotlin for Java场景 2:在 Kotlin for 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); } }

One of the great features about Kotlin is that you can create top level functions and variables. Kotlin 的一大特色是您可以创建顶级函数和变量。 This makes it greate to create "classless" lists of constant fields and functions, which in turn can be used as static functions/fields in Java.这使得创建常量字段和函数的“无类”列表非常有用,这些列表又可以用作 Java 中的static函数/字段。

Scenario 3: Accessing top level fields and functions in Kotlin from Java场景 3:从 Java 访问 Kotlin 中的顶级字段和函数

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

Another notable mention that can be used in Java as "static" fields are Kotlin object classes.另一个可以在 Java 中用作“静态”字段的值得注意的是 Kotlin object类。 These are zero parameter singleton classes that are instantiated lazily on first use.这些是零参数单例类,在第一次使用时被延迟实例化。 More information about them can be found here: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations关于它们的更多信息可以在这里找到: https : //kotlinlang.org/docs/reference/object-declarations.html#object-declarations

However, to access the singleton, a special INSTANCE object is created, which is just as cumbersome to deal with as Companion is.然而,为了访问单例,需要创建一个特殊的INSTANCE对象,它和Companion一样难以处理。 Here's how to use annotations to give it that clean static feel in Java:以下是在 Java 中如何使用注解赋予它干净的static感觉:

Scenario 4: Using object classes场景 4:使用object

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

You need to pass companion object for static method because kotlin don't have static keyword - Members of the companion object can be called by using simply the class name as the qualifier:您需要为静态方法传递伴随对象,因为 kotlin 没有 static 关键字 - 可以通过简单地使用类名作为限定符来调用伴随对象的成员:

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

There are 2 ways you can apply static in Kotlin有两种方法可以在 Kotlin 中应用静态

First make a companion object under class首先在类下做一个伴生对象

For ex:例如:

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

you can call this function as你可以把这个函数称为

Test.Companion.isCheck(2)

Another way we can use is to make an object class我们可以使用的另一种方法是创建一个对象类

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

Happy Coding!快乐编码!

Top-level / companion object for static properties static属性的顶级/ companion object

Top-level顶级

When the properties are somewhat related to a class, define them as top-level properties just before the class declaration:当属性与类有些相关时,在类声明之前将它们定义为顶级属性:

const val MAX_ATTEMPTS = 3
private const val DEFAULT_NAME = "Guest"
private const val MIN_AGE = 16

data class User(val id: String, val name: String = DEFAULT_NAME)

This is similar to the static properties in Java.这类似于 Java 中的static属性。

When the properties are completely independent of any class, you can define them as top-level in a separate file without the class.当属性完全独立于任何类时,您可以在不包含类的单独文件中将它们定义为顶级。

companion object

When the properties are closely related to a class and will be used only in that class, define them inside a companion object :当属性与类密切相关并且仅在该类中使用时,请在companion object定义它们:

data class User(val id: String, val name: String = DEFAULT_NAME) {
    companion object {
        const val DEFAULT_NAME = "Guest"
        const val MIN_AGE = 16
    }
}

Top-level / companion object for static methods static方法的顶级/ companion object

Top-level顶级

Similar to the properties above, when the functions are somewhat related to a class, define them just above the class:与上面的属性类似,当函数与类有些相关时,将它们定义在类的正上方:

fun getAllUsers() { }

fun getProfileFor(userId: String) { }

data class User(val id: String, val name: String)

Usage:用法:

val userList = getAllUsers()

companion object

When the functions are closely related to a class, define them inside a companion object :当函数与类密切相关时,将它们定义在一个companion object

data class User(val id: String, val name: String) {

    companion object {

        fun getAll() { }

        fun profileFor(userId: String) { }
    }
}

Usage:用法:

val userProfile = User.profileFor("34")

This is similar to the static methods in Java.这类似于 Java 中的static方法。

The top-level functions are often more idiomatic to Kotlin.顶级函数通常更符合 Kotlin 的习惯。 A better reason to define functions inside the companion object is when you are extending a companion object with an interface .companion object定义函数的一个更好的理由是当您使用interface扩展companion object时。 An example of this is shown in the singleton section.单例部分显示了一个示例。


Nested class for static class static类的嵌套类

When the classes with related functionalities belong together, they can be grouped together by nesting:当具有相关功能的类属于一起时,可以通过嵌套将它们组合在一起:

class User(val id: String, val name: String) {
    class UserAccess : UserDao {
        override fun add(user: User) { }
        override fun remove(id: String) { }
    }
}

This is equivalent to the static nested classes in Java.这相当于 Java 中的static嵌套类。 The UserAccess class here implements an interface UserDao .这里的UserAccess类实现了一个interface UserDao

Usage:用法:

fun main() {
    val john = User("34", "John")
    val userAccess = User.UserAccess()
    userAccess.add(john)
}

Singleton object for static INSTANCE static INSTANCE单例object

Top-level顶级

When you just want a single object of a class, you no longer need to create a static INSTANCE inside a class like in Java.当您只需要一个类的单个对象时,您不再需要像在 Java 中那样在类中创建static INSTANCE Simply use a top-level object declaration:只需使用顶级object声明:

object UserAccess : UserDao {
    override fun add(user: User) { }
    override fun remove(id: String) { }
}

Notice also how easy it is to extend an interface or a class in a singleton.还要注意在单例中扩展interfaceclass是多么容易。

The code above, under the hood, produces the following static INSTANCE singleton pattern in Java (simplified):上面的代码,在底层,在 Java(简化)中产生了以下static INSTANCE单例模式:

public final class UserAccess implements UserDao {
   public static final UserAccess INSTANCE;

   public void add(User user) { }

   public void remove(String id) { }

   private UserAccess() { }

   static { INSTANCE = new UserAccess();}
}

companion object

When the singleton is closely related to a class use companion object :当单例与类密切相关时,使用companion object

data class User(val id: String, val name: String) {
    companion object : UserDao {
        override fun add(user: User) { }
        override fun remove(id: String) { }
    }
}

This way you get more elegant naming: User.add(john) .通过这种方式,您可以获得更优雅的命名: User.add(john) Also, you make the intent clear that this singleton is only used as a utility for the User class.此外,您明确表示此单例仅用作User类的实用程序。 You can also use the object without the companion keyword inside the class, if you want multiple singletons or groups of functions/properties.如果您想要多个单例或函数/属性组,您也可以在类中使用没有companion关键字的object


companion object for static factory static工厂的companion object

Factory functions in Koltin are created using the companion object . Koltin 中的工厂函数是使用companion object创建的。 Factory functions are useful when you want to provide multiple ways to create an object where the object construction process is complex or when multiple constructors are not expressive enough.当您想要提供多种方法来创建对象时,工厂函数非常有用,但对象构造过程很复杂,或者当多个构造函数不够表达时。

For example, the newInstance() factory function in the following snippet creates a user by generating the id automatically:例如,以下代码段中的newInstance()工厂函数通过自动生成id创建用户:

class User private constructor(val id: Long, val name: String) {
    companion object {
        private var currentId = 0L;
        fun newInstance(name: String) = User(currentId++, name)
    }
}

This is equivalent to the static factory methods in Java.这相当于 Java 中的static工厂方法。

The constructor is kept private but the companion object has access to the constructor . constructorprivatecompanion object可以访问constructor

In the code above, consistency of the next id generation is guaranteed because a companion object is a singleton, only one object will keep track of the id , there won't be any duplicate ids.在上面的代码中,保证了下一代id一致性,因为companion object是单例,只有一个对象会跟踪id ,不会有任何重复的 id。

Also notice that companion objects can have properties ( currentId in this case) to represent state.另请注意,伴随对象可以具有表示状态的属性(在本例中为currentId )。

Usage:用法:

val john = User.newInstance("John")

@JvmStatic for Java interoperability @JvmStatic实现 Java 互操作性

The static concept of Java doesn't exist in Kotlin. Kotlin 中不存在 Java 的静态概念。 A companion object is an instance of a real class called Companion . companion object是名为Companion的真实class的实例。 So, when you call the Kotlin code from Java, an object of the Companion class is first instantiated behind the scenes.因此,当您从 Java 调用 Kotlin 代码时,首先在幕后实例化Companion类的一个对象。 You need to call the function using the Companion object in Java:您需要使用 Java 中的Companion对象调用该函数:

Profile userProfile = User.Companion.profileFor("34");

For the idiomatic Java naming and less verbosity, use @JvmStatic annotation on that function or property:对于惯用的 Java 命名和更少的冗长,在该函数或属性上使用@JvmStatic注释:

companion object {
    @JvmStatic
    fun profileFor(userId: String): Profile { }
}

The @JvmStatic annotation creates a separate pure static copy of the getProfileFor() function. @JvmStatic注释创建了getProfileFor()函数的一个单独的纯static副本。 Now you can use it from Java with regular syntax:现在您可以通过常规语法从 Java 中使用它:

Profile userProfile = User.profileFor("34");

That's it!就是这样! Hope the examples are useful for your projects.希望这些示例对您的项目有用。

Simply you need to create a companion object and put the function in it只需创建一个伴随对象并将函数放入其中

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

To invoke the method from a kotlin class:要从 kotlin 类调用该方法:

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

or Using import或使用导入

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

To invoke the method from a java class:要从 Java 类调用该方法:

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

or by adding @JvmStatic annotation to the method或者通过在方法中添加@JvmStatic 注释

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

or both by adding @JvmStatic annotation to the method and making static import in java或两者都通过在方法中添加 @JvmStatic 注释并在 java 中进行静态导入

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

Kotlin has no any static keyword. Kotlin 没有任何静态关键字。 You can use below code for Java and Kotlin您可以将以下代码用于 Java 和 Kotlin

 object AppHelper {
    @JvmStatic
    fun getAge() : Int = 30
}

Call for Java Class调用 Java 类

AppHelper.getAge();

Call for Kotlin Class呼吁 Kotlin 课程

AppHelper.getAge()

Its work perfectly for me.它非常适合我。 Thanks谢谢

Companion Objects is the alternate of java static keyword and you can make a class or a method as static by declaring them as Companion Objects. 伴随对象是java static关键字的替代形式,您可以通过将它们声明为伴随对象来使类或方法成为静态对象。
You don't need to qualify companion objects with the class name either if you're calling them from within the same class. 如果您是从同一个类中调用伴随对象,则也不需要使用该类名来限定伴随对象。

For example: 例如:

class SomeClass() {

    val id: Int

    init {
       id = nextId++       
    }

    private companion object {
       var nextId = 1
    }
}

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

I would like to add something to above answers.我想在上面的答案中添加一些内容。

Yes, you can define functions in source code files(outside class).是的,您可以在源代码文件(类外)中定义函数。 But it is better if you define static functions inside class using Companion Object because you can add more static functions by leveraging the Kotlin Extensions .但是如果您使用Companion Object在类中定义静态函数会更好,因为您可以通过利用Kotlin Extensions添加更多静态函数。

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

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

And you can call above defined function as you will call any function inside Companion Object.您可以调用上面定义的函数,就像调用 Companion Object 中的任何函数一样。

For Java:对于 Java:

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

Equivalent Kotlin code:等效的 Kotlin 代码:

object  Constants {
const val MAX_CLICK_INTERVAL: Long = 1000}

So for the equivalent of Java static methods is object class in Kotlin.因此,对于 Java 静态方法的等价物是 Kotlin 中的对象类。

To make it short you could use "companion object" to get into Kotlin static world like :简而言之,您可以使用“伴随对象”进入 Kotlin 静态世界,例如:

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

and to make a constant field use "const val" as in the code.并在代码中使用“const val”作为常量字段。 but try to avoid the static classes as it is making difficulties in unit testing using Mockito!.但是尽量避免使用静态类,因为它在使用 Mockito! 进行单元测试时会遇到困难。

For Android using a string from a single activity to all the necessary activity.对于 Android 使用从单个活动到所有必要活动的字符串。 Just like static in java就像java中的静态一样

public final static String TEA_NAME = "TEA_NAME";

Equivalent approach in Kotlin: 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)
    }
}

Another activity where value is needed:另一个需要价值的活动:

val teaName = MainActivity.TEA_NAME

The exact conversion of the java static method to kotlin equivalent would be like this. java 静态方法到 kotlin 等效方法的确切转换是这样的。 eg Here the util class has one static method which would be equivalent in both java and kotlin.例如,这里的 util 类有一个静态方法,它在 java 和 kotlin 中都是等价的。 The use of @JvmStatic is important. @JvmStatic的使用很重要。

Java code:爪哇代码:

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

Kotlin code:科特林代码:

    class Util {
        companion object {
            @JvmStatic
            fun capitalize(text:String): String {
                return text.toUpperCase()
            }
        }
    }

except Michael Anderson's answer, i have coding with other two way in my project.除了迈克尔安德森的回答,我在我的项目中用其他两种方式编码。

First:首先:

you can white all variable to one class.您可以将所有变量都设置为一个类。 created a kotlin file named Const创建了一个名为 Const 的 kotlin 文件

object Const {
    const val FIRST_NAME_1 = "just"
    const val LAST_NAME_1 = "YuMu"
}

You can use it in kotlin and java code您可以在 kotlin 和 java 代码中使用它

 Log.d("stackoverflow", Const.FIRST_NAME_1)

Second:第二:

You can use Kotlin's extension function可以使用 Kotlin 的扩展功能
created a kotlin file named Ext, below code is the all code in Ext file创建了一个名为 Ext 的 kotlin 文件,下面的代码是 Ext 文件中的所有代码

package pro.just.yumu

/**
 * Created by lpf on 2020-03-18.
 */

const val FIRST_NAME = "just"
const val LAST_NAME = "YuMu"

You can use it in kotlin code您可以在 kotlin 代码中使用它

 Log.d("stackoverflow", FIRST_NAME)

You can use it in java code你可以在java代码中使用它

 Log.d("stackoverflow", ExtKt.FIRST_NAME);

Write them directly to files.将它们直接写入文件。

In Java (ugly):在 Java 中(丑陋):

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

In Kotlin:在科特林:

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

Those two pieces of codes are equaled after compilation (even the compiled file name, the file:JvmName is used to control the compiled file name, which should be put just before the package name declaration).这两段代码编译后相等(即使是编译后的文件名, file:JvmName用于控制编译后的文件名,应该放在包名声明之前)。

Let, you have a class Student .让,你有一个类Student And you have one static method getUniversityName() & one static field called totalStudent .您有一个静态方法getUniversityName()和一个名为totalStudent 的静态字段。

You should declare companion object block inside your class.你应该在你的类中声明伴随对象块。

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

Then your class looks like然后你的班级看起来像

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

Then you can use those static method and fields like this way.然后你可以像这样使用那些静态方法和字段。

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

You can achieve the static functionality in Kotlin by Companion Objects您可以通过Companion Objects实现 Kotlin 中的静态功能

  • Adding companion to the object declaration allows for adding the static functionality to an object even though the actual static concept does not exist in Kotlin.即使 Kotlin 中不存在实际的静态概念,也可以向对象声明添加伴侣,从而可以向对象添加静态功能。
  • A companion object can access all members of the class too, including the private constructors.伴随对象也可以访问类的所有成员,包括私有构造函数。
  • A companion object is initialized when the class is instantiated.当类被实例化时,伴随对象被初始化。
  • A companion object cannot be declared outside the class.不能在类外声明伴生对象

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

Members of the companion object can be called by using simply the class name as the qualifier:可以通过简单地使用类名作为限定符来调用伴生对象的成员:

Output:输出:

MyClass.staticField // This is an example of static field Object Decleration

MyClass.getStaticFunction() : // This is an example of static function for Object Decleration

The java code is like as below: java代码如下:

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

will become as below in kotlin: 将在kotlin中变为如下:

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

However, using @JvmStatic annotation on the JVM, we can have members of companion objects generated as real static methods and fields. 但是,在JVM上使用@JvmStatic注释,我们可以将伴随对象的成员生成为真正的静态方法和字段。

Use @JVMStatic Annotation使用@JVMStatic注解

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

A lot of people mention companion objects, which is correct.很多人提到伴随对象,这是正确的。 But, just so you know, you can also use any sort of object (using the object keyword, not class) ie,但是,正如您所知,您也可以使用任何类型的对象(使用 object 关键字,而不是类),即,

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

Use it just like any static method in java:像java中的任何静态方法一样使用它:

StringUtils.toUpper("foobar")

That sort of pattern is kind of useless in Kotlin though, one of its strengths is that it gets rid of the need for classes filled with static methods.不过,这种模式在 Kotlin 中是无用的,它的优势之一是它摆脱了对充满静态方法的类的需求。 It is more appropriate to utilize global, extension and/or local functions instead, depending on your use case.根据您的用例,使用全局、扩展和/或本地函数更合适。 Where I work we often define global extension functions in a separate, flat file with the naming convention: [className]Extensions.kt ie, FooExtensions.kt.在我工作的地方,我们经常使用命名约定在一个单独的平面文件中定义全局扩展函数:[className]Extensions.kt,即 FooExtensions.kt。 But more typically we write functions where they are needed inside their operating class or object.但更常见的是,我们在操作类或对象中需要的地方编写函数。

There is no static keyword in kotlin. kotlin 中没有 static 关键字。 kotlin docs recommends to use package-level functions if u want to follow DRY.如果你想遵循 DRY,kotlin docs 建议使用包级函数。 Create a file with .kt extension and put your method in it.创建一个扩展名为.kt的文件并将您的方法放入其中。

package p
    fun m(){
    //fun body
    }

after compilation m will have a signature of public static final void编译后m将有一个public static final void的签名

and

import p.m

Simply use this approach只需使用这种方法

object Foo{
   fun foo() = println("Foo")
   val bar ="bar"  
}

Foo.INSTANCE.foo()

In Java, we can write in below way在Java中,我们可以用下面的方式编写

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

In Kotlin, we can write in below way在 Kotlin 中,我们可以这样写

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

a companion is used as static in Kotlin.同伴在 Kotlin 中用作静态。

The kotlin documents provider three ways to do that, the first is define function in package,without class: kotlin 文档提供者可以通过三种方式做到这一点,第一种是在包中定义函数,无需类:

package com.example

fun f() = 1

the second is use @JvmStatic annotation:第二种是使用@JvmStatic 注解:

package com.example

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

and the third is use companion object:第三个是使用伴随对象:

package com.example

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

All static member and function should be inside companion block所有静态成员和函数都应该在伴随块内

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

    fun staticMethod() {
    }
  }

If you need a function or a property to be tied to a class rather than to instances of it, you can declare it inside a companion object:如果您需要将一个函数或属性绑定到一个类而不是它的实例,您可以在伴随对象中声明它:

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

The companion object is a singleton, and its members can be accessed directly via the name of the containing class伴生对象是一个单例,可以通过包含类的名称直接访问其成员

val car = Car.makeCar(150)
println(Car.Factory.cars.size)

You can use Companion Objects - kotlinlang您可以使用伴随对象 - kotlinlang

Which it can be shown by first creating that Interface它可以通过首先创建该接口来显示

interface I<T> {

}

Then we have to make a function inside of that interface:然后我们必须在该接口内创建一个函数:

fun SomeFunc(): T

Then after, We need a class:然后,我们需要一个类:

class SomeClass {}

inside that class we need a companion Object inside that class:在该类中,我们需要该类中的一个伴生对象:

companion object : I<SomeClass> {}

inside that Companion Object we need that old SomeFunc function, But we need to over ride it:在 Companion 对象中,我们需要旧的SomeFunc函数,但我们需要覆盖它:

override fun SomeFunc(): SomeClass = SomeClass()

Finally below all of that work, We need something to power that Static function, We need a variable:最后,在所有这些工作之后,我们需要一些东西来为静态函数提供动力,我们需要一个变量:

var e:I<SomeClass> = SomeClass()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM