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

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

    //2
    const val MY_CONST = "something"

    //3
    val myConst = "something"
}

或者…?


当前回答

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

命名约定应该遵循Java约定,并且在从Java代码中使用时应该正确可见(这在某种程度上很难通过伴生对象实现,但无论如何)。

正确的常量声明是:

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

其他回答

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

在Kotlin中声明常量不需要类、对象或伴生对象。您可以声明一个包含所有常量的文件(例如constants。或者你也可以把它们放在任何现有的Kotlin文件中),并直接在文件中声明常量。编译时已知的常量必须用const标记。

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

const val MY_CONST = "something"

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

import package_name.MY_CONST

你可以参考这个链接

对于基元和字符串:

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

我认为这将是把一个包的所有常量放在同一个文件中的最好方法,正如在其他答案中提到的,这避免了创建伴侣对象,这使得这个性能和非常类似于Java constants类。

class Constants {
    object Analytics {
        const val PROJECT_OPEN = "project_open"
        const val PROJECT_CLOSE = "project_close"
    }

    object HTTP {
        const val BASE_URL = "x.y.com"
    }

    object DBConst {
        const val TABLE_NAME = "abc"
    }
}

这可以从这样的代码中引用,使其非常结构化。

Constants.Analytics.PROJECT_OPEN
Constants.HTTP.BASE_URL
Constants.DBConst.TABLE_NAME
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