質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

2回答

19900閲覧

Kotlinのcompanion objectのメリットがわからない

redhat98

総合スコア236

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2018/02/26 03:49

companion object のメリットがイマイチ理解できません。

companion objectはJavaだとstaticに相当するとのことですが、
JavaからKotlinへstaticメソッドをIDEで変換してみたら次のようになりました。

Kotlin

1object Test { 2 3 fun testMethod() { 4 5 } 6}

companion object というキーワードが出てきません。

また、objectとcompanion objectの違いを調べるために、次のようなコードを書いてみました

Kotolin

1class Test1 { 2 companion object { 3 fun test1Method() { 4 println("1") 5 } 6 } 7} 8 9class Test2 { 10 object Test2Inner { 11 fun test2Method() { 12 println("2") 13 } 14 } 15} 16 17class Test3 { 18 companion object Test3Inner { 19 fun test3Method() { 20 println("3") 21 } 22 } 23} 24 25fun main(args: Array<String>) { 26 Test1.test1Method() 27 28 Test2.Test2Inner.test2Method() 29 30 Test3.Test3Inner.test3Method() 31 Test3.test3Method() 32}

companion objectもobjectも、ほぼ同じ動作をしました。
唯一の違いは、objectの方がメソッドの呼び出すときに、冗長な表現になってしまうことくらいです。

companion objectのメリット、objectとcompanion objectの違いはなんですか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/object-declarations.html

を読むとポイントがわかるのではないでしょうか?質問者さんが指摘しておられるとおり「アクセス構文」の違いの他に以下の意味的な違いもあることがわかります。

  • オブジェクト宣言は、初回アクセス時に 遅延して 初期化されます
  • コンパニオンオブジェクトは、対応するクラスが読み込まれた(解決)されたときに初期化され、これは Java の静的初期化子のセマンティクスに一致します

つまり

kotlin

1class MyClass { 2 companion object { 3 ... (A) 4 } 5 ... 6}

こうかくと(A)はMyClassの最初の参照時点で実行されますが、companionでないobjectではそのobjectを最初にアクセスした時点まで(A)は実行されないというわけです。あまりよい例が思いつきませんが、例えばJNIにより一部のメソッドがNativeなものだったとき、MyClassを利用するにはまずダイナミックライブラリーをロードせねばなりません。そういうような場面ではcompanion objectが必要ということになりましょうか。

投稿2018/02/26 04:29

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

redhat98

2018/02/26 06:42

回答ありがとうございます。 初期化のタイミングが違うとのことですが、仰る通り使い所が難しいですね。 実質的にcompanion objectは、表記が短くなるというメリットがなさそう... companion objectを使いこなすには、かなりの技術料が必要そうに感じました。
KSwordOfHaste

2018/02/26 07:01

> 表記が短くなるというメリットがなさそう... 自分が挙げたリンクに「コンパニオンオブジェクトのメンバーは修飾子として単にクラス名を使用して呼び出すことができます」とあり class MyClass {  companion object Factory {   fun create(): MyClass = MyClass()  } } ... MyClass.create()って書けるとありますがこれは表記の短縮とはいえないんでしょうか・・・
KSwordOfHaste

2018/02/26 07:03

> companion objectを使いこなすには、かなりの技術料が必要 そうかなw; インスタンスメソッドではなくてクラスメソッドを書きたい場面はけっこうあると思います。そういう場面でcompanionを使うのが自然じゃないでしょうか?
redhat98

2018/02/26 10:47

> 表記が短くなるというメリットがなさそう すいません、間違えて入力していました。 おっしゃる通り、companion objectを表記は短くなるメリットがあると思います。 >インスタンスメソッドではなくてクラスメソッドを書きたい場面はけっこうあると思います Builderパターンやprivate constructor()にアクセスするとかですか?
KSwordOfHaste

2018/02/26 12:08

> Builderパターンや・・・ そうですね。個人的にはファクトリーパターンをよく使う気がします。
guest

0

投稿2018/02/26 04:12

編集2018/02/26 04:14
tkturbo

総合スコア5572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問