76
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

kotlinで定数を定義する時【const】vs【val】

kotlinで定数を定義する

kotlinで定数を定義する際にはCompanionObjectが使われます。
定数を定義する際にプリミティブ型かStringsであればconstをつけることができますが、constがある時とない時の振る舞いの違いを調べてみました。

class Constants {  
  companion object {
    const val NAME = "taku"
  }
}

constをつけずに定数を定義した場合

class Constants {  
  companion object {
    val NAME = "taku"
  }
}

これをバイトコードで見てみると、

// ================com/hoge/Constants.class =================
// class version 50.0 (50)
// access flags 0x31
public final class com/hoge/Constants {


  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 6 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcom/hoge/Constants; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1A
  private final static Ljava/lang/String; NAME = "taku"
  @Lorg/jetbrains/annotations/NotNull;() // invisible

  // access flags 0x8
  static <clinit>()V
    NEW com/hoge/Constants$Companion
    DUP
    ACONST_NULL
    INVOKESPECIAL com/hoge/Constants$Companion.<init> (Lkotlin/jvm/internal/DefaultConstructorMarker;)V
    PUTSTATIC com/hoge/Constants.Companion : Lcom/hoge/Constants$Companion;
   L0
    LINENUMBER 9 L0
    LDC "taku"
    PUTSTATIC com/hoge/Constants.NAME : Ljava/lang/String;
    RETURN
    MAXSTACK = 3
    MAXLOCALS = 0

  // access flags 0x19
  public final static Lcom/hoge/Constants$Companion; Companion

  // access flags 0x1019
  public final static synthetic access$getNAME$cp()Ljava/lang/String;
  @Lorg/jetbrains/annotations/NotNull;() // invisible
   L0
    LINENUMBER 6 L0
    GETSTATIC com/hoge/Constants.NAME : Ljava/lang/String;
    ARETURN
   L1
    MAXSTACK = 1
    MAXLOCALS = 0

  @Lkotlin/Metadata;(mv={1, 1, 6}, bv={1, 0, 1}, k=1, d1={"\u0000\u000c\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\u0008\u0003\u0018\u0000 \u00032\u00020\u0001:\u0001\u0003B\u0005\u00a2\u0006\u0002\u0010\u0002\u00a8\u0006\u0004"}, d2={"Lcom/hoge/Constants;", "", "()V", "Companion", "production sources for module hoge"})
  // access flags 0x19
  public final static INNERCLASS com/hoge/Constants$Companion com/hoge/Constants Companion
  // compiled from: Constants.kt
}


// ================com/hoge/Constants$Companion.class =================
// class version 50.0 (50)
// access flags 0x31
public final class com/hoge/Constants$Companion {


  // access flags 0x11
  public final getNAME()Ljava/lang/String;
  @Lorg/jetbrains/annotations/NotNull;() // invisible
   L0
    LINENUMBER 9 L0
    INVOKESTATIC com/hoge/Constants.access$getNAME$cp ()Ljava/lang/String;
    ARETURN
   L1
    LOCALVARIABLE this Lcom/hoge/Constants$Companion; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x2
  private <init>()V
   L0
    LINENUMBER 8 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcom/hoge/Constants$Companion; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1001
  public synthetic <init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
   L0
    LINENUMBER 8 L0
    ALOAD 0
    INVOKESPECIAL com/hoge/Constants$Companion.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcom/hoge/Constants$Companion; L0 L1 0
    LOCALVARIABLE $constructor_marker Lkotlin/jvm/internal/DefaultConstructorMarker; L0 L1 1
    MAXSTACK = 1
    MAXLOCALS = 2

  @Lkotlin/Metadata;(mv={1, 1, 6}, bv={1, 0, 1}, k=1, d1={"\u0000\u0014\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\u0008\u0002\n\u0002\u0010\u000e\n\u0002\u0008\u0003\u0008\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\u0008\u0002\u00a2\u0006\u0002\u0010\u0002R\u0014\u0010\u0003\u001a\u00020\u0004X\u0086D\u00a2\u0006\u0008\n\u0000\u001a\u0004\u0008\u0005\u0010\u0006\u00a8\u0006\u0007"}, d2={"Lcom/hoge/Constants$Companion;", "", "()V", "NAME", "", "getNAME", "()Ljava/lang/String;", "production sources for module hoge"})
  // access flags 0x19
  public final static INNERCLASS com/hoge/Constants$Companion com/hoge/Constants Companion
  // compiled from: Constants.kt
}

色々書かれてありますが、NAMEの部分を見てみると、Companionクラスの中のgetNAME()というメソッドを通してNAMEにアクセスしていることが分かります。

javaからだと、Constants.Companion.getNAME()でNAMEにアクセスできます。

constをつけて定数を定義した場合

class Constants {
  companion object {
    const val NAME = "taku"
  }
}

これをバイトコードで見てみると、

// ================com/hoge/Constants.class =================
// class version 50.0 (50)
// access flags 0x31
public final class com/hoge/Constants {


  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 6 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcom/hoge/Constants; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x19
  public final static Ljava/lang/String; NAME = "taku"
  @Lorg/jetbrains/annotations/NotNull;() // invisible

  // access flags 0x8
  static <clinit>()V
    NEW com/hoge/Constants$Companion
    DUP
    ACONST_NULL
    INVOKESPECIAL com/hoge/Constants$Companion.<init> (Lkotlin/jvm/internal/DefaultConstructorMarker;)V
    PUTSTATIC com/hoge/Constants.Companion : Lcom/hoge/Constants$Companion;
    RETURN
    MAXSTACK = 3
    MAXLOCALS = 0

  // access flags 0x19
  public final static Lcom/hoge/Constants$Companion; Companion

  @Lkotlin/Metadata;(mv={1, 1, 6}, bv={1, 0, 1}, k=1, d1={"\u0000\u000c\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\u0008\u0003\u0018\u0000 \u00032\u00020\u0001:\u0001\u0003B\u0005\u00a2\u0006\u0002\u0010\u0002\u00a8\u0006\u0004"}, d2={"Lcom/hoge/Constants;", "", "()V", "Companion", "production sources for module hoge"})
  // access flags 0x19
  public final static INNERCLASS com/hoge/Constants$Companion com/hoge/Constants Companion
  // compiled from: Constants.kt
}


// ================com/hoge/Constants$Companion.class =================
// class version 50.0 (50)
// access flags 0x31
public final class com/hoge/Constants$Companion {


  // access flags 0x2
  private <init>()V
   L0
    LINENUMBER 7 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcom/hoge/Constants$Companion; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1001
  public synthetic <init>(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
   L0
    LINENUMBER 7 L0
    ALOAD 0
    INVOKESPECIAL com/hoge/Constants$Companion.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcom/hoge/Constants$Companion; L0 L1 0
    LOCALVARIABLE $constructor_marker Lkotlin/jvm/internal/DefaultConstructorMarker; L0 L1 1
    MAXSTACK = 1
    MAXLOCALS = 2

  @Lkotlin/Metadata;(mv={1, 1, 6}, bv={1, 0, 1}, k=1, d1={"\u0000\u0012\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\u0008\u0002\n\u0002\u0010\u000e\n\u0000\u0008\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\u0008\u0002\u00a2\u0006\u0002\u0010\u0002R\u000e\u0010\u0003\u001a\u00020\u0004X\u0086T\u00a2\u0006\u0002\n\u0000\u00a8\u0006\u0005"}, d2={"Lcom/hoge/Constants$Companion;", "", "()V", "NAME", "", "production sources for module hoge"})
  // access flags 0x19
  public final static INNERCLASS com/hoge/Constants$Companion com/hoge/Constants Companion
  // compiled from: Constants.kt
}

constをつけた場合には、Companionクラスは存在していますが、getNAMEメソッドがなくなって、Companionクラスを介さずに直接NAMEにアクセスすることができます。

javaからだと、Constants.NAMEでNAMEにアクセスできます。

まとめ

  • constをつけるとgetXXX()がなくなるのでメソッド数が減る。
  • constをつけるとgetXXX()メソッドを一つ挟まずに直接変数にアクセスする。

constがつけれるときはつけたほうが良さそう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
76
Help us understand the problem. What are the problem?