Open2

Kotlin学習 その3

Kohne62Kohne62

JavaからKotlinへのアクセス

  • Kotlinのプロパティには暗黙的にgetter, setterが実装されている
  • JavaからKotlinのクラスプロパティへのアクセスはgetter, setterを通して行う
// Kotlin
class User(val id: Long, var name: String)

// Java
User user = new User(1L, "taro");
user.getId(); // 1L
user.getName(); // "taro"
user.setName("jiro");
  • プロパティの実体であるバッキングフィールドは常にprivateで宣言されているので直接触れることができない
  • @JvmField というアノテーションを使ってアクセスする
// Kotlin
class User(@JvmField val id: Long, var name: String)

// Java
User user = new User(1L, "taro")
user.id; // 1L

パッケージレベルの関数やプロパティを使う場合

// Config.kt
package org.kotlinlang

val CLIENT_ID = "aaaa"
fun hello() { /* ... */ }

// 上の関数は実態としてはKotlinファイルの名前に接尾辞Ktを付与したクラスの中に静的に宣言されている
// Javaから使うには下記のように書く
ConfigKt.getCLIENT_ID() // "aaaa"
ConfigKt.hello()
Kohne62Kohne62
  • オブジェクトやコンパニオンオブジェクトはそれぞれシングルトンのインスタンスが宣言される
  • Kotlin上ではインスタンスへのアクセスを省略して静的にアクセスしているよう書けるが、Javaからは実際のインスタンスを経由しなければならない
// オブジェクト
// INSTANCE を経由する必要がある
DataProviderManager.INSTANCE.registerDataProvider(this);
// コンパニオンオブジェクト
// Companion を経由する必要がある
MainActivity.Companion.createIntent(context);
  • @JvmStaticアノテーションをつけることで静的に宣言できる
object DataProviderManager {
    @JvmStatic
    fun registerDataProvider(provider: DataProvider) {
        // ...
    }
}
class MainActivity: AppCompatActivity() {
    companion object {
        @JvmStatic
        fun createIntent(context: Context): Intent {
            // ...
        }
    }
}

DataProviderManager.registerDataProvider(this)
MainActivity.createIntent(context)

拡張関数を呼び出す

package org.kotlinlang
fun Int.reversed(): Int {
    return this.toString().reversed().toInt()
}

234.reversed() // 432

// Kotlin上では対象のクラスに関数が増えたように見えるが、実際は対象のクラスを第一引数に取る関数が宣言されている
package org.kotlinlang
public final class IntExtensionsKt {
    public static final int reversed(int $receiver) {
        // ...
    }
}

IntExtensionsKt.reversed(234) // 432

関数のオーバーロード

  • 関数がデフォルト引数を持っているとき、Kotlin上ではオーバーロードしているように見える
    ※オーバーロード: 同じ名前でメソッドを定義すること。各メソッドの引数、型、個数が異なるように定義する。
class UserRepository {
    fun get(id: Int, param: String = ""): User {
        return User(1, "")
    }
}

val repository = UserRepository

// オーバーロードしている様に見える
repository.get(10)
repository.get(10, "page=10")   

しかしJavaからは引数をフルセットで渡す必要がある

UserRepository repository = new UserRepository();
repository.get(10, "page=10");
  • @JvmOverloadsアノテーションを使うことで関数のオーバーロードを可能にできる
class UserRepository {
    @JvmOverloads
    fun get(id: Int, param: String = ""): User {
        return User(1, "")
    }
}
UserRepository repository = new UserRepository();
repository.get(10); // OK
repository.get(10, "page=10");