問題の歴史:
Kotlin 1.9以前では、オブジェクトがデータオブジェクトになることはできませんでした。シングルトンで自動的にequals、hashCode、toStringを取得することはできず、データクラスのようにはいきませんでした。data objectの登場でこの制限は解除されました。これにより、値のパターンや列挙型のような用途に適した自動生成メソッドを持つシングルトンオブジェクトを作成できるようになりました。
問題:
以前は、シングルトンオブジェクトの正しいequals()、hashCode()、toString()を取得するために手動で実装するか、他のトリックを使用しなければならず、ボイラープレートが増え、エラーの可能性が高まりました。
解決策:
一意のインスタンスを持つオブジェクトにはデータオブジェクトを使用し、コレクションに渡すため、シリアライズ、比較、デバッグのために標準的なequals/hashCode/toStringの動作が必要です。
コード例:
data object NotAvailable fun checkStatus(status: Any) = when (status) { NotAvailable -> "データがありません" else -> "他のステータス" } val set = setOf(NotAvailable) println(NotAvailable in set) // true println(NotAvailable.toString()) // NotAvailable
主な特徴:
データオブジェクトはプロパティを含むことができますか?
はい、valプロパティのみが可能で、バックフィールドはありません(シングルトンに保存されるものはないため)。
data object Loading { val status: String get() = "読み込み中..." }
データオブジェクトは通常のオブジェクトとequalsの面で何が違いますか?
通常のオブジェクトのequalsは参照の同一性をチェックしますが、データオブジェクトはデータの契約を比較します。ただし、シングルトンの場合、常に同じオブジェクトです。とはいえ、オーバーライドされたequals/hashCodeはコレクションにとっては有用です。
データオブジェクトから継承することはできますか?
いいえ、データオブジェクトはファイナルで、Kotlinの通常のオブジェクトと同様に継承はできません。
すべての状態に対してenumの代わりに異なるデータオブジェクトを使用しました。1年後、文字列によるシリアライズが必要になり、オブジェクト名とタイプを手動で対応付けることになりました。
利点:
欠点:
ネットワークリクエストの戻り値として、特別なステータスのためにデータオブジェクトを使用しました: Loading, Empty, Error。これによりコードはコンパクトで、equals、hashCode、toStringが自動的にサポートされます。
利点:
欠点: