Kotlinで定数を作成することはどのように推奨されますか?命名規則は何ですか?私はドキュメントでそれを見つけられませんでした。
companion object {
//1
val MY_CONST = "something"
//2
const val MY_CONST = "something"
//3
val myConst = "something"
}
それとも…?
Kotlinで、クラスで使用されることになっているローカル定数を作成したい場合は、以下のように作成できます。
val MY_CONSTANT = "Constants"
Javaでpublic static finalのようにパブリック定数をkotlinで作成したい場合は、次のように作成できます。
companion object{
const val MY_CONSTANT = "Constants"
}
コンパニオンオブジェクトを使用しないでください。フードの背後には、フィールドにアクセスできるように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
コンパイル時にわかっている値は(そして私の意見ではそうすべきですが)定数としてマークすることができます。
命名規則はJavaの規則に従うべきであり、Javaコードから使用されるときには適切に表示されるべきです(とにかくコンパニオンオブジェクトで達成するのは難しいですがとにかく).
適切な定数宣言は次のとおりです。
const val MY_CONST = "something"
const val MY_INT = 1
Kotlinで定数を宣言するためにクラス、オブジェクト、またはコンパニオンオブジェクトは必要ありません。すべての定数を含むファイルを宣言するだけで(たとえばConstants.kt)、ファイル内で直接宣言することができます。コンパイル時に認識される定数はconst
でマークする必要があります。
したがって、この場合は、次のようになります。
const val MY_CONST = "something"
その後、次のようにして定数をインポートできます。
import package_name.MY_CONST
あなたはこれを参照することができます link
まず第一に、Kotlinの定数の命名規則はJavaのものと同じです(例:MY_CONST_IN_UPPERCASE)。
あなたはただあなたのconst outsideあなたのクラス宣言を入れなければならない。
2つの可能性:あなたのクラスファイルであなたのconstを宣言してください(あなたのconstはあなたのクラスと明確な関係があります)
private const val CONST_USED_BY_MY_CLASS = 1
class MyClass {
// I can use my const in my class body
}
これらのグローバルconstを格納する場所に専用のconstants.ktファイルを作成します(ここでは、プロジェクト全体で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
}
}
さらに悪いことには constではなくvalとして宣言した場合(コンパイラは無用なオブジェクトと無用な関数を生成するでしょう):
MyClass {
companion object {
val URL_PATH = "https://"
}
}
Kotlinでは、constは単にプリミティブ型を保持できます。関数を渡したい場合は、@ JvmFieldアノテーションを追加する必要があります。コンパイル時には、public static final variableとして変換されます。しかし、それはプリミティブ型よりも遅くなります。それを避けるようにしてください。
@JvmField val foo = Foo()
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
class Myclass {
companion object {
const val MYCONSTANT = 479
}
const
キーワードを使用するか、それをJavaの静的な最終定数にする@JvmField
を使用することができます。
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
どの答えにも記載されていないことは、companion objects
を使用することによるオーバーヘッドです。お分かりのように ここ 、コンパニオンオブジェクトは実際にはオブジェクトであり、それらを作成するとリソースを消費します。さらに、定数を使用するたびに、複数のゲッター関数を通過する必要があるかもしれません。必要なものがいくつかの基本的な定数だけであれば、おそらくval
を使用して より優れたパフォーマンス を取得し、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));
}
}
だからそれらを避けるようにしてください。
ローカル定数
const val NAME = "name"
グローバル定数:
object MyConstants{
val NAME = "name"
val ID = "_id"
var EMAIL = "email"
}
myConstants.NAMEにアクセスする
チェックアウト この記事 。関連するパフォーマンスのトレードオフとともに、定数を格納するためのさまざまな方法について、Niceの概要を説明します。
Kotlinで定数を定義する方法はいくつかありますが、
コンパニオンオブジェクトを使用
companion object {
const val ITEM1 = "item1"
const val ITEM2 = "item2"
}
任意のクラス内で上記のコンパニオンオブジェクトブロックを使用し、このブロック自体内ですべてのフィールドを定義できます。しかし、このアプローチには問題があります、とドキュメントは言います、
コンパニオンオブジェクトのメンバーは他の言語の静的メンバーのように見えますが、実行時にはそれらはまだ実際のオブジェクトのインスタンスメンバーであり、たとえばインターフェイスを実装できます。
コンパニオンオブジェクトを使用して定数を作成し、decompiled bytecodeを確認すると、次のようになります。
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メソッドはまったく必要ありません。
これらのgetメソッドを取り除くには、以下のようにconstの前にvalを使用する必要があります。
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;
}
}
したがって、これは定数を作成する最良の方法です。
プリミティブと文字列の場合
/** 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!"
}
}
}