ボックス化
ボックス化(boxing)とは、プログラミング言語において値型をオブジェクト型(参照型)に変換すること。逆に、ボックス化されたオブジェクトを値型に戻すことをボックス化解除(unboxing)と呼ぶ。
Javaや.NET Frameworkなどの近代的な環境においては、値型(Javaでは原始型がこれに相当する)と参照型という根本的に異なる二種類の型が存在する。参照型のインスタンスはヒープ上の独立した領域に確保される。値型は文脈によって確保される場所は異なるものの、いずれにせよメモリ上に連続的に確保される(例えば、ローカル変数として宣言された場合はスタック上に確保され、参照型のメンバとして宣言された場合は参照型の一部として確保される)。
このように値型と参照型とは根本的に性質の異なるものであるが、さまざまな理由により、値型を参照型に型変換する必要がある場合がある。例えば.NETにおいては、概念上、値型も含めすべての型はSystem.Object型(これは参照型である)の派生型であるため、この型への暗黙的なアップキャストが行える必要がある。またJavaにおいてはコレクションに値型を直接入れることができないため、一度参照型に変換してから入れる必要がある。
次はJavaによる例である。int
型の値をInteger
型のオブジェクトにボックス化し、さらにそれをint
型にボックス化解除している。
int hoge = 2004;
Integer piyo = new Integer(hoge); //ボックス化
int foo = piyo.intValue(); //ボックス化解除
これらの操作を暗黙的に行うことを、自動ボックス化(autoboxing)および自動ボックス化解除(auto-unboxing)と呼ぶ。
int hoge = 2004;
Integer piyo = hoge; //ボックス化
int foo = piyo; //ボックス化解除
一見単純な型変換のように見えるが、ボックス化においてはヒープ上に新しく領域を確保し、そこに値型のデータをコピーするという操作が行われているため注意が必要である。一方、ボックス化解除ではデータのコピーが行われるだけであり、ヒープに領域を確保する必要がないのでパフォーマンスコストは比較的小さい。
自動ボックス化はC#でも取り入れられている。Javaでは JDK 1.5 から導入されている。
コレクションの例
Javaでは、オブジェクト型用のコレクションには、原始型のデータをそのまま要素として追加することはできない。 そこで、原始型のデータはラッパオブジェクトにボックス化して追加し、取り出す時にボックス化解除する。
ArrayList list = new ArrayList();
list.add(5); //こちらはコンパイルエラー
list.add(new Integer(5)); //Integer 型にボックス化してリストに追加する。
Java 1.5以降では自動ボックス化をサポートするので、原始型のデータもあたかもオブジェクトのように扱うことができる。
ArrayList<Integer> list = new ArrayList<Integer>();
//自動的に Integer 型のオブジェクトにボックス化される。
list.add(5);