Kotlinのconstについて

採用はこちら

Kotlinのconstは、プロパティをコンパイル時定数として宣言するための修飾子です。

使い方は const val の形に限られ、var には付けられません。

const val APP_NAME = "MyApp"
const val MAX_RETRY = 3

このように定義した値は、実行時ではなくコンパイル時に確定する定数として扱われます。

目次

valconst valの違い

valconst val も再代入はできませんが、意味は同じではありません。

valの場合

val は、読み取り専用のプロパティです。

ただし、値がコンパイル時に確定している必要はありません。

val createdAt = System.currentTimeMillis()
val message = "Hello".lowercase()

このように、関数の実行結果や実行時に決まる値でも val にはできます。

const valの場合

const val は、読み取り専用であり、かつコンパイル時定数でなければならないプロパティです。

つまり、

  • val は「再代入できない値」
  • const val は「再代入できず、コンパイル時に確定している値」

という違いがあります。

const valを宣言できる場所

const val を宣言できる場所は限定されています。

使えるのは、次のいずれかです。

トップレベル

const val API_VERSION = "v1"

object宣言の中

object Config {
    const val BASE_URL = "https://example.com"
}

companion objectの中

class ApiClient {
    companion object {
        const val TIMEOUT = 5000
    }
}

通常のクラスのインスタンスプロパティには使えない

const を付けられるのは、トップレベル、objectcompanion object のメンバーに限られます。

そのため、通常のクラスのインスタンスプロパティには使えません。

class User {
    const val TYPE = "admin"   // エラー
}

この場合は、companion object に移す必要があります。

class User {
    companion object {
        const val TYPE = "admin"
    }
}

const valにできる型

const val にできるのは、プリミティブ型または String だけです。

たとえば、次のような値は使えます。

const val PORT = 8080
const val SITE_NAME = "My Site"
const val ENABLE_LOG = true

一方で、次のような値は const val にできません。

const val LIST = listOf(1, 2, 3)   // エラー
const val USER = User("A")         // エラー

コレクションや任意のオブジェクトは、コンパイル時定数として扱えないためです。

初期値に使えるもの

const val の初期値には、コンパイル時に評価できる定数式が必要です。

使えるのは、たとえば次のようなものです。

  • 数値や文字列のリテラル
  • 定数同士の算術演算
  • 文字列連結
  • 他の定数を使った式

使える例

const val ANSWER = 2 * 21
const val HELLO = "Hello, " + "world"
const val NEXT = ANSWER + 1

使えない例

const val NOW = System.currentTimeMillis() // エラー
const val LOWER = "Hello".lowercase()      // エラー
const val HASH = "".hashCode()             // エラー

関数呼び出しを含む式は、コンパイル時定数にはできません。

custom getterやdelegationは使えない

const val は、値そのものが固定されている必要があります。

そのため、custom getter を持つことはできません。

const val NAME: String
    get() = "Kotlin"   // エラー

また、delegation も使えません。

const val VALUE by lazy { 123 }   // エラー

const val は「あとで計算する値」ではなく、「最初から完全に確定している値」である必要があります。

アノテーションでの使い方

アノテーション引数には、コンパイル時定数が必要です。

直接書く場合

文字列リテラルなどをそのまま書くなら、const は不要です。

@Deprecated("Use new API instead")
fun oldApi() {}

プロパティ経由で渡す場合

プロパティ経由で値を渡すなら、そのプロパティはコンパイル時定数でなければならないため、const val が必要です。

const val DEPRECATED_MSG = "Use new API instead"

@Deprecated(DEPRECATED_MSG)
fun oldApi() {}

つまり、正確には「アノテーション引数そのものにはコンパイル時定数が必要であり、プロパティ経由で渡すなら const val が必要」という理解になります。

Javaとの相互運用での位置づけ

const val は、コンパイル時定数として扱われるという性質を持っています。

そのため、Kotlinの中だけでなく、Javaとの相互運用の文脈でも便利です。

ただし、Javaからどう見えるかは宣言場所などにも関係するため、まずは「Java連携でも扱いやすい定数になることがある」と理解しておくと安全です。

const valにできない例のまとめ

次のようなものは const val にできません。

関数呼び出し

const val UUID = generateId()   // エラー

実行時評価が必要な式

val name = "kotlin"
const val UPPER = name.uppercase()   // エラー

オブジェクト生成

const val USER = User("A")   // エラー

コレクション

const val NUMBERS = listOf(1, 2, 3)   // エラー

通常クラスのインスタンスメンバー

class Sample {
    const val VALUE = 1   // エラー
}

const valenumの違い

const valenum は役割が異なります。

const valが向いている場合

単一の固定値を表したいときです。

const val STATUS_OK = 200

enumが向いている場合

複数の選択肢や状態を、型安全に表したいときです。

enum class Status {
    OK, ERROR, LOADING
}

つまり、

  • 単なる固定値なら const val
  • 状態や種類の集合なら enum

という使い分けになります。

実務でよくある使い方

実務では、定数を整理するために objectcompanion object と組み合わせることがよくあります。

objectにまとめる例

object ApiConstants {
    const val BASE_URL = "https://api.example.com"
    const val TIMEOUT = 5000
    const val RETRY_COUNT = 3
}

呼び出し側は次のようになります。

val url = ApiConstants.BASE_URL

companion objectに置く例

そのクラスに属する定数なら、companion object に置くのが自然です。

class HttpClient {
    companion object {
        const val DEFAULT_TIMEOUT = 3000
    }
}

呼び出し側は次のようになります。

val timeout = HttpClient.DEFAULT_TIMEOUT

constを使いすぎない方がよい理由

const は便利ですが、固定値なら何でも付ければよいわけではありません。

次のようなものは、通常の val や設定ファイル、環境変数などで管理する方が自然です。

  • 実行時に決まる値
  • 環境によって変わる値
  • 将来的に差し替えやすくしたい値
  • オブジェクトやコレクション

たとえば、開発環境と本番環境で変わるURLは、const より設定管理の仕組みで扱う方が適しています。

実務での使い分け

const valを使うべきケース

  • 本当に固定の文字列や数値
  • アノテーション引数で使う値をプロパティ化したいとき
  • Java連携を含む定数定義
  • 名前付きの固定値として明確に管理したいとき

普通のvalを使うべきケース

  • 実行時に決まる値
  • 関数呼び出しの結果
  • オブジェクトやコレクション
  • 環境や設定によって変わる値

まとめ

Kotlinのconstは、ただの読み取り専用プロパティではなく、コンパイル時定数として扱える特別な val です。

使える場所、型、初期化式には制約がありますが、そのぶん

  • 定数であることを明確に示せる
  • アノテーションで使える
  • 定数定義を整理しやすい

という利点があります。

一言でまとめると、const val「実行前に確定している単純な固定値」を宣言するためのものです。

以上、Kotlinのconstについてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次