如何在Kotlin中创建常量?什么是命名惯例?我没有在文档中找到它。
companion object {
//1
val MY_CONST = "something"
//2
const val MY_CONST = "something"
//3
val myConst = "something"
}
或......?
答案 0 :(得分:72)
在Kotlin中,如果你想创建应该在课堂上使用的局部常量,那么你可以像下面那样创建它
val MY_CONSTANT = "Constants"
如果你想在kotlin中创建一个公共常量,比如java中的 public static final ,你可以按照以下步骤创建它。
companion object{
const val MY_CONSTANT = "Constants"
}
答案 1 :(得分:41)
避免使用伴侣对象。在引擎盖后面,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
答案 2 :(得分:16)
编译时已知的值可以(在我看来应该)标记为常量。
命名约定应遵循Java约定,并且在从Java代码中使用时应该是正确可见的(使用伴随对象很难实现它,但无论如何)。
正确的常量声明是:
<p style="word-wrap: break-word;">{aVeryLongLine}</p>
答案 3 :(得分:14)
在Kotlin中声明常量时,不需要类,对象或伴随对象。您可以声明一个包含所有常量的文件(例如 Constants.kt )并直接声明文件中的常量。编译时已知的常量必须标有const
。
所以,在这种情况下,它应该是:
const val MY_CONST = "something"
然后你可以使用:
导入常量 import package_name.MY_CONST
您可以参考此link
答案 4 :(得分:7)
首先,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
}
创建一个专用的constants.kt文件,用于存储这些全局const(在这里您想在整个项目中广泛使用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://
}
}
这更更少,因为在幕后,当生成字节码时,会创建一个无用的对象:
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批注。在编译时,它将被转换为公共静态最终变量。但这比原始类型要慢。尝试避免它。
@JvmField val foo = Foo()
答案 5 :(得分:6)
如果您将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)
Java反编译:
public final class MyClassKt {
public static final int MY_CONST0 = 0;
public static final int MY_CONST1 = 1;
}
// rest of MyClass.java
答案 6 :(得分:6)
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)
答案 7 :(得分:5)
像val
一样,用const
关键字定义的变量是不可变的。这里的区别在于const
用于编译时已知的变量。
声明变量const
就像在Java中使用static
关键字一样。
让我们看看如何在Kotlin中声明一个const变量:
const val COMMUNITY_NAME = "wiki"
用Java编写的类似代码将是:
final static String COMMUNITY_NAME = "wiki";
添加到以上答案-
@JvmField
用于指示Kotlin编译器不生成 该属性的获取器/设置器,并将其公开为字段。
@JvmField
val COMMUNITY_NAME: "Wiki"
静态字段
在命名对象或伴随对象中声明的Kotlin属性 该命名对象或 包含伴随对象的类。
通常这些字段是私有的,但是可以通过以下方式之一公开它们:
@JvmField
注释; lateinit
修饰符; const
修饰符。此处有更多详细信息-https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#instance-fields
答案 8 :(得分:2)
class Myclass {
companion object {
const val MYCONSTANT = 479
}
您有两个选择可以使用const
关键字,或使用@JvmField
使其成为java的静态最终常量。
class Myclass {
companion object {
@JvmField val MYCONSTANT = 479
}
如果您使用@JvmField
注释,那么在编译之后,您将按照在java中调用它的方式输入常量。
就像你在java中调用它一样,当你在代码中调用伴随常量时,编译器会替换它。
但是,如果使用const关键字,则常量的值将被内联。内联我的意思是实际值在编译后使用。
所以这里总结一下编译器会为你做什么:
//so for @JvmField:
Foo var1 = Constants.FOO;
//and for const:
Foo var1 = 479
答案 9 :(得分:2)
任何答案中未提及的是使用companion objects
的开销。正如您可以阅读here,伴侣对象实际上是对象,创建它们会消耗资源。此外,每次使用常量时,您可能需要经历多个getter函数。如果您需要的只是一些原始常数,那么您最好使用val
来获得better performance并避免使用companion object
。
TL; DR;文章:
使用随播对象实际上会转换此代码
class MyClass {
companion object {
private val TAG = "TAG"
}
fun helloWorld() {
println(TAG)
}
}
进入此代码:
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));
}
}
所以尽量避免它们。
答案 10 :(得分:1)
本地常量:
const val NAME = "name"
全局常量:
object MyConstants{
val NAME = "name"
val ID = "_id"
var EMAIL = "email"
}
访问MyConstants.NAME
答案 11 :(得分:0)
对于基元和字符串:
/** The empty String. */
const val EMPTY_STRING = ""
其他情况:
/** The empty array of Strings. */
@JvmField val EMPTY_STRING_ARRAY = arrayOfNulls<String>(0)
示例:
/*
* Copyright 2018 Vorlonsoft LLC
*
* Licensed under The MIT License (MIT)
*/
package com.vorlonsoft.android.rate
import com.vorlonsoft.android.rate.Constants.Utils.Companion.UTILITY_CLASS_MESSAGE
/**
* Constants Class - the constants class of the AndroidRate library.
*
* @constructor Constants is a utility class and it can't be instantiated.
* @since 1.1.8
* @version 1.2.1
* @author Alexander Savin
*/
internal class Constants private constructor() {
/** Constants Class initializer block. */
init {
throw UnsupportedOperationException("Constants$UTILITY_CLASS_MESSAGE")
}
/**
* Constants.Date Class - the date constants class of the AndroidRate library.
*
* @constructor Constants.Date is a utility class and it can't be instantiated.
* @since 1.1.8
* @version 1.2.1
* @author Alexander Savin
*/
internal class Date private constructor() {
/** Constants.Date Class initializer block. */
init {
throw UnsupportedOperationException("Constants.Date$UTILITY_CLASS_MESSAGE")
}
/** The singleton contains date constants. */
companion object {
/** The time unit representing one year in days. */
const val YEAR_IN_DAYS = 365.toShort()
}
}
/**
* Constants.Utils Class - the utils constants class of the AndroidRate library.
*
* @constructor Constants.Utils is a utility class and it can't be instantiated.
* @since 1.1.8
* @version 1.2.1
* @author Alexander Savin
*/
internal class Utils private constructor() {
/** Constants.Utils Class initializer block. */
init {
throw UnsupportedOperationException("Constants.Utils$UTILITY_CLASS_MESSAGE")
}
/** The singleton contains utils constants. */
companion object {
/** The empty String. */
const val EMPTY_STRING = ""
/** The empty array of Strings. */
@JvmField val EMPTY_STRING_ARRAY = arrayOfNulls<String>(0)
/** The part 2 of a utility class unsupported operation exception message. */
const val UTILITY_CLASS_MESSAGE = " is a utility class and it can't be instantiated!"
}
}
}
答案 12 :(得分:0)
有几种方法可以在Kotlin中定义常量,
使用伴随对象
companion object {
const val ITEM1 = "item1"
const val ITEM2 = "item2"
}
您可以在任何类内使用上面的伴随对象块,并在此块本身内定义所有字段。文档说,但是这种方法存在问题,
即使伴随对象的成员看起来像其他语言中的静态成员,在运行时它们仍然是真实对象的实例成员,并且可以例如实现接口。
当您使用随播对象创建常量并查看反编译的字节码时,您将看到以下内容,
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;
}
}
从这里您可以轻松地看到文档中的内容,即使伴随对象的成员看起来像其他语言中的静态成员,但在运行时它们仍然是真实对象的实例成员超出要求。
现在有了另一种方式,其中我们不需要使用伴随对象,如下所示,
object ApiConstants {
val ITEM1: String = "item1"
}
再次,如果您看到上述代码段的字节码的反编译版本,则会发现类似的内容,
public final class ApiConstants {
private static final String ITEM1 = "item1";
public static final ApiConstants INSTANCE;
public final String getITEM1() {
return ITEM1;
}
private ApiConstants() {
}
static {
ApiConstants var0 = new ApiConstants();
INSTANCE = var0;
CONNECT_TIMEOUT = "item1";
}
}
现在,如果您看到上面的反编译代码,它将为每个变量创建get方法。完全不需要此get方法。
要摆脱这些获取方法,您应在 val 之前使用 const ,如下所示,
object ApiConstants {
const val ITEM1: String = "item1"
}
现在,如果您看到以上代码段的反编译代码,您会发现它更容易阅读,因为它对代码的后台转换最少。
public final class ApiConstants {
public static final String ITEM1 = "item1";
public static final ApiConstants INSTANCE;
private ApiConstants() {
}
static {
ApiConstants var0 = new ApiConstants();
INSTANCE = var0;
}
}
因此,这是创建常量的最佳方法。