Kotlin中的常数 - 建议创建它们的方法是什么?

问题描述 投票:77回答:10

如何在Kotlin中创建常量?什么是命名惯例?我没有在文档中找到它。

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

    //2
    const val MY_CONST = "something"

    //3
    val myConst = "something"
}

要么 ...?

android kotlin constants
10个回答
77
投票

在Kotlin中,如果你想创建应该在类中使用的本地常量,那么你可以创建它,如下所示

val MY_CONSTANT = "Constants"

如果你想在kotlin中创建一个公共常量,比如java中的public static final,你可以按照以下方式创建它。

companion object{

     const val MY_CONSTANT = "Constants"

}

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

50
投票

避免使用伴侣对象。在引擎盖后面,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


17
投票

在编译时已知的值可以(并且在我看来应该)标记为常量。

命名约定应遵循Java约定,并且在从Java代码中使用时应该是正确可见的(使用伴随对象很难实现,但无论如何)。

适当的常量声明是:

const val MY_CONST = "something"
const val MY_INT = 1

15
投票

您不需要用于在Kotlin中声明常量的类,对象或伴随对象。您可以声明一个包含所有常量的文件(例如Constants.kt)并直接声明文件中的常量。编译时已知的常量必须用const标记。

所以,在这种情况下,它应该是:

const val MY_CONST = "something"

然后你可以使用以下方法导入常量:

import package_name.MY_CONST

你可以参考这个link


8
投票

如果你把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

8
投票

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

我应该如何创建它?

1. As a top level value (recommended)

你只需要把你的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://
    }
}

2. Declare it in a companion object (or an object declaration)

这更不干净,因为在引擎盖下,当生成字节码时,会创建一个无用的对象:

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://"
    }
}

Note :

在kotlin中,const只能保存原始类型。如果要将函数传递给它,则需要添加@JvmField注释。在编译时,它将被转换为公共静态最终变量。但它比原始类型慢。尽量避免它。

@JvmField val foo = Foo()

3
投票

在任何答案中没有提到的东西是使用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));
    }
}

所以尽量避免它们。


3
投票
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

2
投票

局部常数:

const val NAME = "name"

全局常数:

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

访问MyConstants.NAME

© www.soinside.com 2019 - 2024. All rights reserved.