建议如何在Kotlin中创建常量?命名规则是什么?我在文档里没有找到。

companion object {
    //1
    val MY_CONST = "something"

    //2
    const val MY_CONST = "something"

    //3
    val myConst = "something"
}

或者…?


当前回答

首先,Kotlin中常量的命名约定与java中相同(例如:MY_CONST_IN_UPPERCASE)。

我应该如何创建它?

1. 作为顶级值(推荐)

你只需要把const放在类声明的外面。

两种可能:在类文件中声明const(你的const与你的类有明确的关系)

private const val CONST_USED_BY_MY_CLASS = 1

class MyClass { 
    // I can use my const in my class body 
}

创建一个专用的常量。在这里你想要在你的项目中广泛使用你的const文件:

package com.project.constants
const val URL_PATH = "https:/"

然后你只需要把它导入到你需要的地方:

import com.project.constants

MyClass {
    private fun foo() {
        val url = URL_PATH
        System.out.print(url) // https://
    }
}

2. 在伴生对象(或对象声明)中声明它

这就不那么干净了,因为在底层,当字节码生成时,会创建一个无用的对象:

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

更糟糕的是,如果你将它声明为val而不是const(编译器将生成一个无用的对象+一个无用的函数):

MyClass {
    companion object {
        val URL_PATH = "https://"
    }
}

注意:

在kotlin中,const只能保存原始类型。如果希望将调用函数的结果分配给它,则需要添加@JvmField注释。在编译时,它将被转换为一个公共静态final变量。但是它比原始类型要慢。尽量避免。

@JvmField val foo = Foo()

其他回答

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
}

}

在任何地方访问值

val value = MyConstant.PI
val value = MyConstant.sumValue(10,5)

像val一样,用const关键字定义的变量是不可变的。这里的区别在于,const用于编译时已知的变量。

声明一个变量const很像在Java中使用static关键字。

让我们看看如何在Kotlin中声明一个const变量:

const val COMMUNITY_NAME = "wiki"

用Java编写的类似代码是:

final static String COMMUNITY_NAME = "wiki";

加上上面的答案-

@JvmField可以用来指示Kotlin编译器不生成 getter /setter,并将其公开为字段。

 @JvmField
 val COMMUNITY_NAME = "Wiki"

静态字段

在命名对象或伴生对象中声明的Kotlin属性 将有静态支持字段,无论是在该命名对象或 包含伴生对象的类。

通常这些字段是私有的,但它们可以通过以下方式之一公开:

@JvmField注释; lateinit修饰语; const修饰符。

更多详情请访问:https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#instance-fields

避免使用伴随对象。在底层,为可访问的字段创建了getter和setter实例方法。从技术上讲,调用实例方法比调用静态方法代价更大。

public class DbConstants {
    companion object {
        val TABLE_USER_ATTRIBUTE_EMPID = "_id"
        val TABLE_USER_ATTRIBUTE_DATA = "data"
    }

而是在object中定义常量。

推荐的做法:

object DbConstants {
    const val TABLE_USER_ATTRIBUTE_EMPID = "_id"
    const val TABLE_USER_ATTRIBUTE_DATA = "data"
}

并像这样全局访问它们: DbConstants。TABLE_USER_ATTRIBUTE_EMPID

如果你把const val valName = valValue放在类名之前,这样就会创建一个

public static final YourClass。Kt会有公共的静态最终值。

科特林:

const val MY_CONST0 = 0
const val MY_CONST1 = 1
data class MyClass(var some: String)

Java反编译:

public final class MyClassKt {
    public static final int MY_CONST0 = 0;
    public static final int MY_CONST1 = 1;
}
// rest of MyClass.java

当地常量:

const val NAME = "name"

全局常量:

object MyConstants{
    val NAME = "name"
    val ID = "_id"
    var EMAIL = "email"
}

访问MyConstants。的名字