Jod*_*oro 112 android constants kotlin
如何在Kotlin中创建常量?什么是命名惯例?我没有在文档中找到它.
companion object {
//1
val MY_CONST = "something"
//2
const val MY_CONST = "something"
//3
val myConst = "something"
}
Run Code Online (Sandbox Code Playgroud)
要么 ...?
AaR*_*RiF 98
在Kotlin中,如果你想创建应该在类中使用的本地常量,那么你可以创建它,如下所示
val MY_CONSTANT = "Constants"
Run Code Online (Sandbox Code Playgroud)
如果你想在kotlin中创建一个公共常量,比如java中的public static final,你可以按照以下方式创建它.
companion object{
const val MY_CONSTANT = "Constants"
}
Run Code Online (Sandbox Code Playgroud)
sud*_*esh 74
避免使用伴侣对象.在引擎盖后面,getter和setter实例方法是为可访问的字段创建的,并且调用实例方法在技术上比调用静态方法更昂贵.
public class DbConstants {
companion object {
val TABLE_USER_ATTRIBUTE_EMPID = "_id"
val TABLE_USER_ATTRIBUTE_DATA = "data"
}
Run Code Online (Sandbox Code Playgroud)
而是定义常量object.
推荐做法:
object DbConstants {
const val TABLE_USER_ATTRIBUTE_EMPID = "_id"
const val TABLE_USER_ATTRIBUTE_DATA = "data"
}
Run Code Online (Sandbox Code Playgroud)
并像这样访问全局:
DbConstants.TABLE_USER_ATTRIBUTE_EMPID
pio*_*rpo 19
在编译时已知的值可以(并且在我看来应该)标记为常量.
命名约定应遵循Java约定,并且在从Java代码中使用时应该是正确可见的(使用伴随对象很难实现,但无论如何).
适当的常量声明是:
const val MY_CONST = "something"
const val MY_INT = 1
Run Code Online (Sandbox Code Playgroud)
Abd*_*ood 15
您不需要用于在Kotlin中声明常量的类,对象或伴随对象.您可以声明一个包含所有常量的文件(例如Constants.kt)并直接声明文件中的常量.编译时已知的常量必须标记为const.
所以,在这种情况下,它应该是:
const val MY_CONST = "something"
然后你可以使用以下方法导入常量:
import package_name.MY_CONST
你可以参考这个链接
A.M*_*ode 12
首先, Kotlin中常量的命名约定与Java中的约定相同(例如:MY_CONST_IN_UPPERCASE)。
您只需要将const 放在类声明之外即可。
两种可能:在类文件中声明您的const(您的const与您的类有明确的关系)
private const val CONST_USED_BY_MY_CLASS = 1
class MyClass {
// I can use my const in my class body
}
Run Code Online (Sandbox Code Playgroud)
创建一个专用的constants.kt文件,在其中存储这些全局const(在这里您想在整个项目中广泛使用const):
package com.project.constants
const val URL_PATH = "https:/"
Run Code Online (Sandbox Code Playgroud)
然后,您只需将其导入所需的位置即可:
import com.project.constants
MyClass {
private fun foo() {
val url = URL_PATH
System.out.print(url) // https://
}
}
Run Code Online (Sandbox Code Playgroud)
这是多少吸尘器因为罩下,当产生的字节代码,则创建一个无用对象:
MyClass {
companion object {
private const val URL_PATH = "https://"
const val PUBLIC_URL_PATH = "https://public" // Accessible in other project files via MyClass.PUBLIC_URL_PATH
}
}
Run Code Online (Sandbox Code Playgroud)
更糟糕的是,如果将其声明为val而不是const(编译器将生成无用的对象+无用的函数):
MyClass {
companion object {
val URL_PATH = "https://"
}
}
Run Code Online (Sandbox Code Playgroud)
在kotlin中,const只能保存基本类型。如果要向其传递函数,则需要添加@JvmField批注。在编译时,它将被转换为公共静态最终变量。但这比原始类型要慢。尽量避免它。
@JvmField val foo = Foo()
Run Code Online (Sandbox Code Playgroud)
如果您将您const val valName = valValue的班级名称放在前面,则它将创建一个
public static final YourClass.Kt将具有public static final值。
科特林:
const val MY_CONST0 = 0
const val MY_CONST1 = 1
data class MyClass(var some: String)
Run Code Online (Sandbox Code Playgroud)
Java反编译:
public final class MyClassKt {
public static final int MY_CONST0 = 0;
public static final int MY_CONST1 = 1;
}
// rest of MyClass.java
Run Code Online (Sandbox Code Playgroud)
像 一样val,用const关键字定义的变量是不可变的。这里的区别在于const它用于编译时已知的变量。
声明一个变量const很像static在 Java 中使用关键字。
让我们看看如何在 Kotlin 中声明一个 const 变量:
const val COMMUNITY_NAME = "wiki"
Run Code Online (Sandbox Code Playgroud)
用 Java 编写的类似代码是:
final static String COMMUNITY_NAME = "wiki";
Run Code Online (Sandbox Code Playgroud)
添加到上面的答案 -
@JvmField用于指示 Kotlin 编译器不要为此属性生成 getter/setter 并将其公开为字段。
@JvmField
val COMMUNITY_NAME = "Wiki"
Run Code Online (Sandbox Code Playgroud)
静态字段
在命名对象或伴随对象中声明的 Kotlin 属性将在该命名对象或包含伴随对象的类中具有静态支持字段。
通常这些字段是私有的,但它们可以通过以下方式之一公开:
@JvmField 注解;lateinit 修饰符;const 修饰符。更多细节在这里 - https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#instance-fields
有几种方法可以在 Kotlin 中定义常量,
使用伴生对象
companion object {
const val ITEM1 = "item1"
const val ITEM2 = "item2"
}
Run Code Online (Sandbox Code Playgroud)
您可以在任何类中使用上面的伴随对象块,并在该块本身内定义所有字段。但这种方法有一个问题,文档说,
尽管伴生对象的成员看起来像其他语言中的静态成员,但在运行时它们仍然是真实对象的实例成员,并且可以实现接口等。
当您使用伴随对象创建常量并查看反编译的字节码时,您会看到如下所示的内容,
companion object {
const val ITEM1 = "item1"
const val ITEM2 = "item2"
}
Run Code Online (Sandbox Code Playgroud)
从这里你可以很容易地看到文档所说的内容,即使伴生对象的成员看起来像其他语言中的静态成员,但在运行时它们仍然是真实对象的实例成员,它做了超出要求的额外工作。
现在有另一种方式,我们不需要像下面这样使用伴生对象,
object ApiConstants {
val ITEM1: String = "item1"
}
Run Code Online (Sandbox Code Playgroud)
同样,如果您看到上面片段的字节码的反编译版本,您会发现类似的内容,
ClassName.Companion Companion = ClassName.Companion.$$INSTANCE;
@NotNull
String ITEM1 = "item1";
@NotNull
String ITEM2 = "item2";
public static final class Companion {
@NotNull
private static final String ITEM1 = "item1";
@NotNull
public static final String ITEM2 = "item2";
// $FF: synthetic field
static final ClassName.Companion $$INSTANCE;
private Companion() {
}
static {
ClassName.Companion var0 = new ClassName.Companion();
$$INSTANCE = var0;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您看到上面的反编译代码,它正在为每个变量创建 get 方法。根本不需要这个 get 方法。
要摆脱这些 get 方法,您应该在val之前使用const ,如下所示,
object ApiConstants {
const val ITEM1: String = "item1"
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您看到上面代码片段的反编译代码,您会发现它更容易阅读,因为它对您的代码进行的后台转换最少。
object ApiConstants {
val ITEM1: String = "item1"
}
Run Code Online (Sandbox Code Playgroud)
所以这是创建常量的最佳方式。
class Myclass {
companion object {
const val MYCONSTANT = 479
}
Run Code Online (Sandbox Code Playgroud)
您有两种选择,您可以使用const关键字或使用@JvmField使其成为java 静态最终常量的。
class Myclass {
companion object {
@JvmField val MYCONSTANT = 479
}
Run Code Online (Sandbox Code Playgroud)
如果您使用@JvmField注释,那么在它编译之后,常量就会以您在 java 中调用它的方式放入。
就像您在 java 中调用它一样,当您在代码中调用伴随常量时,编译器将为您替换它。
但是,如果您使用 const 关键字,则常量的值将被内联。内联是指在编译后使用实际值。
所以在这里总结一下编译器将为您做的事情:
//so for @JvmField:
Foo var1 = Constants.FOO;
//and for const:
Foo var1 = 479
Run Code Online (Sandbox Code Playgroud)
任何答案中都没有提到的是使用的开销companion objects。正如您可以在此处阅读的那样,伴生对象实际上是对象,并且创建它们会消耗资源。此外,每次使用常量时,您可能都需要执行多个 getter 函数。如果您需要的只是类的几个实例上的一些原始常量,那么您可能最好使用它val来获得更好的性能并避免companion object. 如果您的类有很多实例,那么代价就是更高的内存消耗,因此每个人都应该做出自己的决定。
TL;博士; 文章的:
使用伴生对象实际上将这个 Kotlin 代码变成:
class MyClass {
companion object {
private val TAG = "TAG"
}
fun helloWorld() {
println(TAG)
}
}
Run Code Online (Sandbox Code Playgroud)
进入这段Java代码:
public final class MyClass {
private static final String TAG = "TAG";
public static final Companion companion = new Companion();
// synthetic
public static final String access$getTAG$cp() {
return TAG;
}
public static final class Companion {
private final String getTAG() {
return MyClass.access$getTAG$cp();
}
// synthetic
public static final String access$getTAG$p(Companion c) {
return c.getTAG();
}
}
public final void helloWorld() {
System.out.println(Companion.access$getTAG$p(companion));
}
}
Run Code Online (Sandbox Code Playgroud)
Kotlin 静态和常量值和方法声明
object MyConstant {
@JvmField // for access in java code
val PI: Double = 3.14
@JvmStatic // JvmStatic annotation for access in java code
fun sumValue(v1: Int, v2: Int): Int {
return v1 + v2
}
Run Code Online (Sandbox Code Playgroud)
}
随时随地访问价值
val value = MyConstant.PI
val value = MyConstant.sumValue(10,5)
Run Code Online (Sandbox Code Playgroud)
局部常量:
const val NAME = "name"
Run Code Online (Sandbox Code Playgroud)
全局常量:
object MyConstants{
val NAME = "name"
val ID = "_id"
var EMAIL = "email"
}
Run Code Online (Sandbox Code Playgroud)
访问 MyConstants.NAME