Kotlinのobject:構文とシングルトンオブジェクトの実践的使用

著者: IT Sectr 公開日: 2026-06-21 読了時間: 9 分

object はKotlinにおいて、デフォルトで遅延初期化とスレッドセーフを備えたシングルトンオブジェクトを作成する宣言的な方法です。objectキーワードは、単一のインスタンスでクラス全体を置き換え、シングルトン、companion object、匿名オブジェクト、静的ユーティリティの宣言に使用されます。JetBrains Kotlin Documentation(2026)によると、object declarationはJVM環境でシングルトンを実装する最もシンプルで安全な方法です。

重要ポイント

  • object — 単一インスタンスのシングルトンクラスを宣言するキーワード
  • 遅延初期化 — objectはクラス読み込み時ではなく、最初のアクセス時に作成される
  • Companion object — Kotlinの静的メンバーに相当(staticキーワードはなし)
  • Object expression — その場でメソッドをオーバーライドする匿名オブジェクト
  • スレッドセーフ — objectの初期化は保証されたthread-safe

Kotlinのobjectとは?

object はKotlinにおける特別な宣言形式で、クラスを定義すると同時にその唯一のインスタンス(シングルトン)を作成します。これはクラス宣言とインスタンス作成を1つの構文に統合したハイブリッドです。

Javaでシングルトンを作成するには、プライベートコンストラクタ、静的フィールド、getInstanceメソッド、スレッドセーフ処理が必要です。Kotlinのobjectはこれを1行のコードで行います: object MySingleton { }。コンパイラはJVMバイトコードのstatic initializerメカニズムを使用して、自動的にスレッドセーフな遅延初期化を生成します。

Kotlin言語仕様(2026)によると、object declarationはプライベートコンストラクタと静的ブロックで初期化される静的INSTANCEフィールドを持つfinalクラスにコンパイルされます。これによりJVMレベルでの初期化のアトミック性が保証されます。

シングルトンオブジェクト(object declaration)

Object declaration(シングルトンオブジェクト)は、objectキーワードの後に名前を付けて宣言します。オブジェクトの本体には、プロパティ、メソッド、initブロックを含めることができ、他のクラスやインターフェースを継承できます。

kotlin
object DatabaseManager {
    private val connection: String = "jdbc:postgresql://localhost:5432/app"
    
    fun query(sql: String): List<Map<String, Any>> {
        // クエリを実行中
        return emptyList()
    }
}

// 使用法
DatabaseManager.query("SELECT * FROM users")

DatabaseManagerの初期化は最初のアクセス時に発生します—遅延かつスレッドセーフに。追加の同期コードは不要です。

objectの継承

Objectは通常のクラスやインターフェースを継承できます。これにより、単一インスタンスを持つ抽象クラスやインターフェースの実装としてobjectを使用できます。

kotlin
interface Logger {
    fun log(message: String)
}

object ConsoleLogger : Logger {
    override fun log(message: String) {
        println("[LOG] $message")
    }
}

Companion object

companion objectは、companionキーワードを使ってクラス内で宣言される特別なobjectです。Kotlinにはstaticキーワードがないため、静的メンバーの代わりとなります。

kotlin
class ApiClient {
    companion object {
        private const val BASE_URL = "https://api.example.com"
        
        fun create(): ApiClient {
            return ApiClient()
        }
    }
}

// ApiClientインスタンスを作成せずに呼び出し
val client = ApiClient.create()

Companion objectは名前を持つことができ(デフォルトはCompanion)、インターフェースを実装し、拡張関数で拡張できます。Javaの静的メソッドとは異なり、companion objectは完全なオブジェクトであり、引数として渡したり変数に格納したりできます。

Kotlinベストプラクティス(2026)によると、companion objectはファクトリメソッド、定数、クラスに関連する静的ユーティリティに使用されます。companion objectの過剰な使用は避けることが推奨されます—無関係なユーティリティにはトップレベル関数が適しています。

@JvmStaticアノテーション

Java互換性のために、companion objectのメソッドに@JvmStaticを付けることができます。これによりJVMバイトコードで実際の静的メソッドが生成され、Companion構文なしでJavaコードからアクセス可能になります。

Object expressions(匿名オブジェクト)

Object expressionは、個別の名前付きクラスを宣言せずに、クラスやインターフェースのメソッドをオーバーライドするためにその場で作成される匿名オブジェクトです。

kotlin
val handler = object : Runnable {
    override fun run() {
        println("タスクを実行しました")
    }
}

thread(handler)

Object expressionsは、実行ごとに新しいインスタンスを作成する点でobject宣言とは異なります。シングルトンではなく、名前もありません。匿名オブジェクトはラムダと同様にクロージャから変数をキャプチャできます。

匿名クラスが1つの型しか継承できないJavaとは異なり、Kotlinのobject expressionは同時に複数の型を継承できます。

kotlin
interface Clickable {
    fun click()
}

abstract class View {
    abstract fun render()
}

val button = object : View(), Clickable {
    override fun render() = println("ボタンをレンダリング中")
    override fun click() = println("ボタンがクリックされました")
}

実用的な使用シナリオ

ObjectはKotlinで最も多用途な構文の1つで、多くのシナリオで使用されます。

Repositoryシングルトン

Androidプロジェクトでは、複数のインスタンスが不要なRepositoryを宣言するためにobjectがよく使用されます。単一のインスタンスによりデータの一貫性が保証されます。

kotlin
object UserRepository {
    fun getUser(id: Int): User? {
        // ユーザーを取得中
        return null
    }
}

companion objectによるファクトリメソッド

Companion objectを使ったファクトリメソッドは、複数のコンストラクタに代わる方法です。名前付きファクトリメソッドによりコードが自己文書化されます。

kotlin
data class GsonParser {
    companion object {
        fun create(): GsonParser = GsonParser()
        fun createPretty(): GsonParser = GsonParser()
    }
}

定数と列挙型

Objectは定数のコンテナとして機能し、Javaのstatic finalフィールドを置き換えます。Objectは継承をサポートしており、構成階層を作成できます。

Kotlin標準ライブラリ(2026)によると、object declarationはKotlinでシングルトンを作成する最も効率的な方法であり、double-checked lockingの実装を凌駕し、Javaのenumシングルトンに匹敵します。

よくある質問

objectは通常のクラスとどう違うのですか?

Objectはクラスを宣言すると同時にその唯一のインスタンスを作成します。通常のクラスはコンストラクタを介して複数のインスタンスを持つことができます。

object declarationはいつ初期化されますか?

遅延 — オブジェクトへの最初のアクセス時です。それまではメモリは割り当てられず、initブロックのコードも実行されません。

objectはコンストラクタを持てますか?

いいえ、objectは明示的なコンストラクタを持つことはできません。初期化はinitブロックで行われ、オブジェクトへの最初のアクセス時に1回だけ呼び出されます。

companion objectは通常のobjectとどう違うのですか?

companion objectはクラス内で宣言されたobjectです。そのメンバーはインスタンスを作成せずにクラス名を介してアクセス可能で、Javaの静的メンバーを置き換えます。

object declarationsはマルチスレッド環境で安全ですか?

はい、objectの初期化はJVMの静的初期化子のおかげで完全にスレッドセーフです。追加の同期は不要です。

まとめ

  • object — 遅延かつスレッドセーフな初期化を備えた宣言的シングルトン
  • companion object — Kotlinの静的メンバー、ファクトリメソッド、定数
  • Object expression — クロージャからの変数キャプチャ付きその場での匿名オブジェクト
  • 継承 — objectは複数の型を含むクラスやインターフェースを継承可能
  • パフォーマンス — JVM static initializerによる初期化、double-checked lockingのオーバーヘッドなし
  • 使用法 — シングルトンサービス、repository、定数、ファクトリ、リスナーアダプター
  • 制限 — 明示的なコンストラクタなし、JVMあたり1インスタンス

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください