はじめに
Genericsが使うのでボックス化について意識することは減りました。
が、ボックス化について人に説明する機会があったので曖昧だったところを自分の為にまとめておきます。
ボックス化
値型をobject型に代入するときに行われる処理。
参照型であることが必要な場面においても値型を使用できるようにする仕組み。
- 値型はスタック、参照型はヒープ上に実値が置かれる。
- object型は参照型なので、値型をobject型に代入したときに実値はヒープにコピーされる。(ボックス化)
- ヒープに実値コピーされるとき、元の型情報も付与される。
ボックス化解除
ボックス化された値型のコピーを取り出すこと
- ボックス化されたobject型は実値がヒープ上に置かれている。
- ボックス化されたobject型を元の型に戻す(キャスト)するときに実値がスタックにコピーされる。(ボックス化解除)
- 型情報が間違えていたときはInvalidCastExceptionが発生する。
パフォーマンス影響
簡単な代入と比べて、ボックス化およびボックス化解除は負荷の大きいプロセスです。 値型をボックス化するときは、新しいオブジェクトを割り当てて構築する必要があります。 ボックス化ほどではありませんが、ボックス化解除に必要なキャストも大きな負荷がかかります。 詳しくは、「パフォーマンス」をご覧ください。
デメリット
- ボックス化はオブジェクトの一時的なコピーを生成するため、コストがかかる。
- ボックス化解除はオブジェクトの一時的なコピーを生成するため、コストがかかる。
- ボックス化解除時のキャストにもコストがかかる。
- ヒープ上の領域確保は、スタックと比べると重たい処理。
- キャスト時、型情報が間違えていたときはランタイムエラー(InvalidCastException)が発生する。
ボックス化を起こさないために
- object型を使用しない
- Genericsを使用する