Programmingバックエンド開発者

Kotlinにおけるコンパニオンオブジェクトとは何ですか?その特徴と制限は何ですか?ファクトリーメソッドや静的状態を作成するためにコンパニオンオブジェクトをどのように使用しますか?

Hintsage AIアシスタントで面接を突破

回答。

Kotlinにおけるコンパニオンオブジェクト(companion object)は、companionキーワードを使用してクラス内に宣言されたオブジェクトであり、Javaの静的メンバーに似た静的メソッドやプロパティをグループ化することを可能にします。Javaのstaticとは異なり、Kotlinの各コンパニオンオブジェクトは完全なオブジェクトであり、バイトコードレベルでは、そのメンバーへのアクセスが静的にコンパイルされます。

主な特徴と制限:

  • デフォルト名 — 明示的に指定しない限り、オブジェクトはCompanionと呼ばれます。
  • コンパニオンオブジェクトは任意のインターフェースを実装するため、ファクトリーメソッドを作成するのに便利です。
  • コンパニオンオブジェクト内では、外部クラスのプライベートメンバーにアクセスできます。
  • 各クラスには1つのコンパニオンオブジェクトのみ存在できます。
  • コンパニオンオブジェクトのメンバーには、クラス名を通じて静的にアクセスすることも、オブジェクトのメンバーとしてアクセスすることもできます。

例:

class MyFactory private constructor(val value: Int) { companion object { fun create(x: Int): MyFactory = MyFactory(x) } } val instance = MyFactory.create(10)

注意が必要な質問。

なぜ、マルチスレッドアプリケーションにおいてcompanion object内に状態(例えば、可変変数)を保存することが推奨されないのですか?

例を含む回答:

可変状態をコンパニオンオブジェクト内に置くと、それはクラスの全インスタンスとスレッド間で共有されるため、追加の同期なしにレースコンディションを引き起こす可能性があります。

class Counter { companion object { var count = 0 fun increment() { count++ } } } Counter.increment() // 同時呼び出し時のレースコンディション

このテーマに関する知識不足から生じる実際のエラーの例。


歴史

Androidプロジェクトで、開発者たちはデバッグスイッチを管理するために環境設定をcompanion object内にまとめました。これにより、異なるフラグメントが同じグローバル値を変更し、非同期遷移時に予期しない動作が発生しました。


歴史

バックエンドで、一部の機能が可変キャッシュと共にcompanion objectに移行されました。高負荷時にエラーが発生し、同期の欠如によりデータの不整合状態が生じました。


歴史

初心者開発者は、コンパニオンオブジェクトのみにインターフェースを実装しようとし、その後クラスをそのインターフェースとして使用できると考えていました。その結果、コンパニオンはクラスに関連付けられた唯一のオブジェクトであり、クラス自体ではないため、クラスをコンパニオンオブジェクトとして渡すことができないという問題に直面しました。