Kotlinのトップレベル宣言について
公式ドキュメント関連部
Kotlinでは以下をトップレベル宣言(パッケージに対しての宣言)することが可能
- インターフェース(sealed interface)
- クラス(data class/object/value class/sealed class/enum class)
- プロパティ
- 関数
- typealias
※Javaではクラスのみ(クラス内部に定義して)アクセスするところを、Kotlinではクラスに直接属さないように定義して、それに対してアクセスが可能
内部的には
トップレベルに複数宣言されたクラスやインターフェースはそれぞれの名称のクラス(クラスファイル)を生成
トップレベルに宣言されたプロパティや関数はtypealiasはファイル名Ktというクラス(クラスファイル)を生成してそこに属させている
クラスの宣言数
Kotlinでは1ファイル中に複数のクラスを宣言することが可能
コンパイル後はクラス名=ファイル名としてクラスファイルが生成される
typealias
typealias OpenAlias = String
internal typealias InternalAlias = String
private typealias PrivateAlias = String
Javaからは型エイリアスは参照できない
型エイリアスを使ったプロパティや関数はJava側では元になっている方として認識される
Javaからは<Kotlinファイル名>Ktというクラスが自動的に生成されてそこに定義される
トップレベル関数
fun openFunction(): Unit {
println("open")
}
internal fun internalFunction(): Unit {
println("internal")
}
private fun privateFunction(): Unit {
println("private")
}
Javaからは<Kotlinファイル名>Ktというクラスが自動的に生成されているのでそのクラスのstaticメソッドとしてアクセス可能
トップレベルプロパティ
val openProperty = "openProperty"
internal val internalProperty = "internalProperty"
private val privateProperty = "privateProperty"
const val constProperty = "constProperty"
javaからは<Kotlinファイル名>Ktというクラスが自動的に生成されてそのクラスにconstがない場合はgetアクセッサメソッドが生成されているのでアクセッサメソッド経由でアクセス、constがある場合はアクセッサメソッドは生成されず、直接該当のプロパティにstaticアクセスできる
余談
トップレベルプロパティや関数が所属するクラスのクラス名はデフォルトでは
定義した<Kotlinのファイル名>Ktとなるが@file:JvmName("name")
アノテーションを付与することで任意に変更が可能
普通にやると
複数のファイルに同一の@file:JvmName
を付与した場合はコンパイルエラーになる
裏技
@file:JvmMultifileClass
アノテーションを合わせて付与することで各ファイルの内容をマージしてクラスファイル生成できる
※但しメンバ名が被っている場合は当たり前のようにInteliJが怒ってくれます!本当にできる子です
companion object VS top-level
staticファクトリ-だけはprivateなプライマリコンストラクタにアクセスできないのでcompanion objectにせざる負えない
それ以外はなるべくトップレベルが推奨されてるって感じかな