はじめに
Anyは「すべての非null型の共通の親」Any?は「nullを含む、すべての型の共通の親」
つまり Kotlin の型階層の**最上位(Top Type)**です。
1. Kotlin の型階層
Kotlin の型階層を図で表すとこうなります:
Any? ← すべての型(nullを含む)
│
├── Any ← null 以外すべて
│ ├── String
│ ├── Int
│ ├── Unit
│ ├── ...
│ └── Nothing (すべての下)
2. Any の基本
Any は「すべてのクラスの親」
val x: Any = "Hello"
val y: Any = 42
val z: Any = true
すべてOK。
なぜなら String, Int, Boolean などすべてが Any のサブタイプだからです。
Javaでの対応関係
| Kotlin | Java |
|---|---|
Any |
java.lang.Object |
つまり、Javaの Object に相当します。
ただしKotlinでは「プリミティブ型」も Any のサブタイプなので、完全に一致ではありません。
3. Any のメソッド
Any にはすべてのオブジェクトが持つ最低限の3つのメソッドがあります:
public open class Any {
public open operator fun equals(other: Any?): Boolean
public open fun hashCode(): Int
public open fun toString(): String
}
つまり、Kotlin の全クラスはこの3つを継承しています。
4. Any? の基本
Any は null を含みませんが、
Any? は nullを含めたすべての値 を表します。
val a: Any = "Hello"
// val b: Any = null // ❌ コンパイルエラー
val c: Any? = null // ✅ OK
| 型 | null許容 | 代表例 |
|---|---|---|
Any |
❌ |
1, "Hello", Unit
|
Any? |
✅ |
1, "Hello", Unit, null
|
5. Any? は “最上位” の型
Kotlin の 型階層の頂点(Top Type) は Any? です。
つまり:
-
Any?は「nullを含むあらゆる値を代入可能」 - 逆に、
Nothingは「そのすべての下(Bottom Type)」
代入例:
val a: Any? = "Hello"
val b: Any? = 42
val c: Any? = null
val d: Any? = Unit
val e: Any? = throw Exception() // Nothing も代入OK
6. Any? と Nothing の関係(上下関係)
Any? ← Top Type(すべてを含む)
│
└── Any ← null以外すべて
│
└── Nothing ← Bottom Type(何もない)
| 型 | 位置 | 意味 |
|---|---|---|
Any? |
最上位 | すべて(null含む) |
Any |
上位 | 非nullすべて |
Nothing |
最下位 | 値が存在しない(throw等) |
7. 実際の使いどころ
① 汎用的な変数や引数
fun printAny(value: Any) {
println(value.toString())
}
printAny("Hello")
printAny(123)
printAny(Unit)
② nullを許す汎用関数なら Any?
fun describe(x: Any?) {
println("Value: $x")
}
describe("Hello")
describe(null)
8. スマートキャストと型チェック
Any? 型の値を扱うときは、
is / !is 演算子とスマートキャストが便利。
fun printType(value: Any?) {
when (value) {
is String -> println("文字列: ${value.uppercase()}")
is Int -> println("整数: ${value + 1}")
null -> println("nullです")
else -> println("その他の型: $value")
}
}
出力:
文字列: HELLO
整数: 43
nullです
9. Any と Generics の関係
ジェネリック型の上限境界(Upper Bound)は Any? です。
つまり、明示しない限りすべての型パラメータは Any? を継承します。
fun <T> identity(x: T): T = x
は実際には:
fun <T : Any?> identity(x: T): T = x
という意味になります。
10. 実務での型設計ポイント
| ケース | 適切な型 | 理由 |
|---|---|---|
| nullを許さない汎用関数 | Any |
型安全性を保ちたい |
| nullも扱いたい汎用関数 | Any? |
null許容値を含む |
| すべての値(throw含む)を許したい | Any? |
Kotlin最上位 |
| 戻らない関数の型 | Nothing |
最下位 |
まとめ
| 型 | 説明 | null許可 | 代表的な用途 |
|---|---|---|---|
| Any | すべての非null型の親 | ❌ | オブジェクト共通型、ジェネリック上限 |
| Any? | null含むすべての型 | ✅ | どんな値でも受け取る引数など |
| Nothing | 値が存在しない(Bottom) | N/A |
throw, TODO()
|
Anyは「すべての非null型の親」
Any?は「nullを含むすべての型の親」
Nothingは「すべての型の子」
この3つを理解すれば、
Kotlin の 型安全 と null安全 の仕組みが完全に見えてきます。