在Kotlin中没有静态关键字。

在Kotlin中表示静态Java方法的最佳方法是什么?


当前回答

在kotlin中没有静态关键字。如果你想遵循DRY, kotlin文档建议使用包级函数。 创建一个扩展名为.kt的文件,并将您的方法放在其中。

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

编译后m将会有一个public static final void的签名

and

import p.m

其他回答

这对我也有用

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

从芬兰湾的科特林

Bell.ring()

从Java

Bell.ring()

使用@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)
                }
            }
}

kotlin文档提供了三种方法, 第一个是在包中定义函数,没有类:

package com.example

fun f() = 1

第二个是使用@JvmStatic注释:

package com.example

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

第三个是使用伴侣对象

package com.example

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

尽管这是2年多一点的现在,并有很多伟大的答案,我看到一些其他的方法得到“静态”Kotlin字段的缺失。下面是Kotlin-Java静态互操作的示例指南:

Scenario 1: Creating a static method in 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的回答提供了更多的深度,在这种情况下绝对应该参考。


下一个场景处理在Kotlin中创建静态字段,这样Java就不必在不需要静态函数的情况下一直调用KotlinClass.foo()。

Scenario 2: Creating a static variable in 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); } }


Kotlin的一个伟大特性是您可以创建顶级函数和变量。这使得创建常量字段和函数的“无类”列表变得非常好,而这些列表又可以用作Java中的静态函数/字段。

Scenario 3: Accessing top level fields and functions in Kotlin from 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); } }


另一个值得注意的可以在Java中作为“静态”字段使用的是Kotlin对象类。这些是在第一次使用时惰性实例化的零参数单例类。更多信息可以在这里找到:https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations

但是,要访问单例对象,需要创建一个特殊的INSTANCE对象,处理它和处理Companion一样麻烦。下面是如何在Java中使用注释来给它一种干净的静态感觉:

Scenario 4: Using 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); } }

如果你需要一个函数或属性绑定到一个类,而不是它的实例,你可以在一个伴随对象中声明它:

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

伴生对象是一个单例对象,它的成员可以通过包含类的名称直接访问

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