0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Kotlin】Kotlin の不変(invariant)──「in」でも「out」でもない型パラメータ

Posted at

はじめに

Kotlin のジェネリクスには 3 つの変性 (variance) モードがあります:

変性の種類 Kotlin キーワード Java 記法 意味
共変 out ? extends T 出すだけ(読み取り専用)
反変 in ? super T 入れるだけ(書き込み専用)
不変 (なし) T 両方使えるが、代入不可(安全のため)

1. 不変 (invariant) とは?

不変とは、**「型パラメータのサブタイプ関係が維持されない」**ことです。
つまり、

Box<String>Box<Any> の間には継承関係がない。

class Box<T>(var value: T)

val stringBox: Box<String> = Box("Hello")
// val anyBox: Box<Any> = stringBox // ❌ コンパイルエラー

Box<T> は不変なので、型を変えて代入することはできません。


2. なぜ不変なのか?

もし Box<String>Box<Any> として扱えたら、
次のような危険なコードが通ってしまいます。

class Box<T>(var value: T)

val stringBox: Box<String> = Box("Hello")
val anyBox: Box<Any> = stringBox // 仮に許可されたとしたら...

anyBox.value = 123 // Int を代入
println(stringBox.value) //  String じゃなくなってしまう!

これが 型安全性の破壊
Kotlin はこの危険を避けるために、
Tinvariant(不変) にすることで「代入禁止」にしています。


3. 不変はデフォルト

Kotlin のジェネリクスは、明示しない限りすべて不変 です。

class Container<T>(val item: T)

val a: Container<String> = Container("A")
// val b: Container<Any> = a // ❌ 不変なので代入できない

不変をベースにして、必要に応じて out または in を明示する設計が Kotlin の基本思想です。


4. 使い分けの指針

シーン 修飾子 意味
出力専用(返すだけ) out List<out T> 読み取り専用。共変。
入力専用(受け取るだけ) in MutableList<in T> 書き込み専用。反変。
入力・出力どちらも使う (なし) MutableList<T> 不変(安全のため代入禁止)。

5. 例:MutableList<T> は不変

val strings: MutableList<String> = mutableListOf("A", "B")
// val anys: MutableList<Any> = strings // ❌ 不変なので代入不可

MutableList<T>読み書き両方できる ため、
安全性を保つために 不変 (invariant) に設計されています。


6. 関数型との関係

関数型 (A) -> B は、入力と出力が自動的に変性指定されています:

部分 変性 意味
引数(A) in(反変) 消費する
戻り値(B) out(共変) 生み出す

逆に、クラスの型パラメータが入出力両方に使われている 場合は不変になります。

class Transformer<T> {
    fun input(value: T) { /* in */ }
    fun output(): T { /* out */ TODO() }
}

T が in/out の両方に使われているため、安全性のために不変でなければなりません。


まとめ

概念 Kotlin 記法 意味 代入関係
共変 (Covariant) out 出力専用 サブタイプ可(Producer<String>Producer<Any>)
反変 (Contravariant) in 入力専用 逆サブタイプ可(Consumer<Number>Consumer<Int>)
不変 (Invariant) なし 入出力両方 代入不可(安全性優先)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?