LoginSignup
162
83

More than 3 years have passed since last update.

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

Last updated at Posted at 2017-10-13

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がつけれるときはつけたほうが良さそう。

162
83
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
162
83