web-dev-qa-db-ja.com

タイプが「ボックス化」されているとはどういう意味ですか?

一部の言語で「ボックス化」と呼ばれる型について聞いたことがあります。

Javaでは、「オートボクシング」について聞いたことがあります。これは何ですか?型のラッパークラスはありますか?ボックス化された型またはボックス化されていない型を使用している場合、コードはどのように変更されますか?

45
Nick Heiner

一部のデータ型は「プリミティブ」と見なされます。つまり、オブジェクトのように扱われず、オブジェクトのプロパティがありません。

ほとんどのプラットフォームでは、整数と文字はプリミティブであるがボックス化できるタイプの例です。

ボクシングとは、それらをオブジェクトにラップして、オブジェクトの動作を持つようにすることです。

正確な意味と動作は、使用している言語によって異なります。一部の言語(Smalltalkなど...私が実行していたときは少なくとも戻ってきます...)はプリミティブ型を許可せず、すべてをオブジェクトであると見なしますが、それに関連してパフォーマンスが低下します。その日のプロセッサーは、有用な処理を行うために、生の数値と生のメモリーを処理する必要があります。ボックス化された2つの整数を追加する場合は、たとえば、舞台裏でプリミティブ型に「ボックス化解除」され、数値が追加されてから、新しい整数にボックス化されます。

62
Eric J.

Javaのより具体的な情報:

オートボクシングを使用すると、Javaでbooleanintなどを自動的にオブジェクトバージョンBooleanおよびIntegerに自動的に変換できます。逆もまた可能です。

例えば:

int a = 3; // no boxing is happening
Integer b = 3;  // newer versions of Java automatically convert the int 3 to Integer 3
int c = b;  // these same versions also automatically convert Integer 3 to int 3

オートボクシングを持たないJavaの古いバージョンでは、このコードで同じことを行う必要があります。

int a = 3;  // works the same
Integer b = new Integer(3);  //must set up a Integer object manually
int c = b.intValue(); //must change Integer object to a primitive

ただし、手動で操作する必要があるシナリオもあります。たとえば、次のような2つのメソッドを持つクラスがあるとします。

assertEquals(int a, int b);
assertEquals(Object a, Object b)

今、これを行おうとすると:

Integer a = 3;
int b = 3;
assertEquals(a, b);  // this will not compile

これが機能しない理由は、aからintへのボックス化を解除するか、bからIntegerへのボックス化を解除する必要があるかを判断できないためです。したがって、どのメソッドシグネチャを呼び出す必要があるかはあいまいです。これを修正するには、次のいずれかを実行できます。

assertEquals((int) a, b);
assertEquals(a, (Integer) b);
19
TM.

はい、ボックス化とは、値の型を受け取り、それを参照型でラップすることを意味します。 Java導入されたオートボクシングなので、次のことができます:

void foo(Object bar) {}
//...
    foo(1);

また、Javaは自動的にint 1をIntegerに変換します。以前のバージョンでは、次のようにする必要があります。

foo(new Integer(1));

オートボクシングは、Javaで最も有用です。ジェネリックスでプリミティブを使用できないため、リストにintを格納するには、List<Integer>を作成する必要があります。そして、ボックス化されたリストにintを入れます。

12
sepp2k

ボックス型とは、値がヒープ上のブロックに割り当てられ、ポインターを通じて参照されることを意味します。これは、追加の間接参照を犠牲にして、ランタイムの実装の均一性に役立ちます(汎用関数の作成が容易になります)。

3
Pascal Cuoq

ボックス化とは、通常の値タイプを取り、その周囲にオブジェクトを作成したことを意味します。箱に入れるようなものです。オブジェクトを構築するオーバーヘッドがあるため、これは一般に回避されます。

1
Alex Baranosky

一般に、コレクションを操作するときは、オブジェクトの配列を扱います。 Javaのような言語では、プリミティブとオブジェクトの間に違いがあります。プリミティブが「ボックス化」されると、それは基本的にプリミティブのラッパーにすぎないため、オブジェクトを期待している残りのフレームワークでニースを再生します。

オートボクシングは、プリミティブをオブジェクトに入れたり、プリミティブをオブジェクトから透過的に引き出したりするだけの行為なので、自分で行う追加の手順について心配する必要はありません。

1
MattC