自从谷歌将Kotlin作为Android的一流语言以来,关于如何使用Kotlin(“Java风格”)执行某些操作的问题越来越多。最常见的是如何在Kotlin中使static
变量。那么如何使Kotlin静态
变量和函数?
你不能。至少在一个纯粹的Kotlin项目中。
Kotlin没有static
的概念。static
在Kotlin-Java项目中的工作方式是通过使用Kotlin类上的注释来告诉JVM所需的变量/函数应该作为static
公开给Java类。
下面是Kotlin的示例指南-Javastatice
互操作(答案最初发布在Kotlin中Java静态方法的等价物是什么?):
场景1:在Kotlin中为Java创建静态方法
科特林
@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);
}
}
@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中的静态
函数/字段。
场景3:从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!")
}
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中用作“静态”字段的是Kotlinobject
类。这些是零参数的单例类,在第一次使用时会被懒洋洋地实例化。有关它们的更多信息可以在这里找到:https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations
但是,要访问单例,需要创建一个特殊的instance
对象,该对象的处理与companion
一样麻烦。以下是如何使用注释使其在Java中具有干净的static
感觉:
场景4:使用object
类
科特林
// There is no more need for the @file:JvmName() annotation. The object class below already handles the proper naming.
//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);
}
}
我希望能够将类实例保存到公共静态变量中,但我不知道如何在Kotlin中做到这一点。
本文向大家介绍PHP静态成员变量和非静态成员变量详解,包括了PHP静态成员变量和非静态成员变量详解的使用技巧和注意事项,需要的朋友参考一下 数据成员可以分静态变量、非静态变量两种. 静态成员:静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于
问题内容: 我有一个带有静态实例的android java类,其中包含一个用户信息。但是,在极少数情况下,当用户使用我的应用程序时,该静态实例中的变量之一会在一段时间后变为null。该Java类是全局的(未附加到任何活动)。是什么原因造成的? 编辑:该变量永远不会更改,除非在应用程序启动期间。我已经检查过调用它的函数永远不会被调用一次以上(adb logcat证明了当我添加一条日志表明正在被调用时
本文向大家介绍C++中静态成员函数与静态成员变量(static ),包括了C++中静态成员函数与静态成员变量(static )的使用技巧和注意事项,需要的朋友参考一下 C++中静态成员函数与静态成员变量(static ) 这篇介绍了静态成员函数与静态成员变量,是我的读书笔记,我希望它够简短但又比较全面,起到复习的作用。如果有一些C++知识记不清楚了,它可以帮你很快回忆起来。 复习C语言的stati
我不知道什么时候在程序中使用一个静态/非静态变量。 我理解非静态/静态变量之间的区别,但我只是不知道何时使用每一个变量。那么在上面的代码中,为什么函数不能是静态的呢?(什么时候应该是静态的?)
问题内容: 我试图弄清楚如何声明一个静态变量,其范围仅限于Swift中的函数。 在C中,这可能看起来像这样: 在Objective-C中,基本上是相同的: 但是我似乎无法在Swift中做这样的事情。我尝试通过以下方式声明变量: 但是这些都会导致错误。 第一个抱怨“静态属性只能在类型上声明”。 第二个抱怨“期望的声明”(在哪里)和“期望的模式”(在哪里) 第三条抱怨“一行上的连续语句必须用’;’分隔