ホームページ > Java > &#&チュートリアル > Javaの自動ボックス化とアンボックス化の詳細な分析

Javaの自動ボックス化とアンボックス化の詳細な分析

高洛峰
リリース: 2017-01-24 14:16:01
オリジナル
1566 人が閲覧しました

これは jdk1.5 以降に導入された新しいコンテンツです。私は公開することが最高の思い出であると主張するので、思い出をブログに置き換えることにしました:
Java 言語仕様には次のように書かれています: 多くの場合、パッケージ化と解凍は、コンパイラー自体 (この場合、パッケージ化はボックス化と呼ばれ、アンパックはアンボックス化と呼ばれます)
実際、私自身の理解によれば、自動ボックス化は、Java のオブジェクト指向に準拠するために、基本的なデータ型をオブジェクト Type にカプセル化するものとして単純に理解できます。 ; たとえば、例として int を使用します:

//声明一个Integer对象 
Integer num = 10; 
//以上的声明就是用到了自动的装箱:解析为 
Integer num = new Integer(10);以上就是一个很好的体现,因为10是属于基本数据类型的,原则上它是不能直接赋值给一个对象Integer的,但jdk1.5后你就可以进行这样的声明,这就是自动装箱的魅力 
自动将基本数据类型转化为对应的封装类型。成为一个对象以后就可以调用对象所声明的所有的方法 
自动拆箱:故名思议就是将对象重新转化为基本数据类型: 
//装箱 
Integer num = 10; 
//拆箱 
int num1 = num;自动拆箱有个很典型的用法就是在进行运算的时候:因为对象时不恩直接进行运算的,而是要转化为基本数据类型后才能进行加减乘除 
Integer num = 10; 
//进行计算时隐含的有自动拆箱 
System.out.print(num--);哈哈 应该感觉很简单吧,下面我再来讲点稍微难点的, 
//在-128~127 之外的数 
Integer num1 = 297; Integer num2 = 297; 
System.out.println("num1==num2: "+(num1==num2)); 
// 在-128~127 之内的数 
Integer num3 = 97; Integer num4 = 97; 
System.out.println("num3==num4: "+(num3==num4)); 打印的结果是:num1==num2: false num3==num4: true
ログイン後にコピー

これは、整数と int の自動ボックス化およびボックス化解除の Java の設計に起因します。これは、フライウェイト パターン (フライウェイト) と呼ばれるパターンです
再利用を増やすためJava は次のように定義しています。自動ボックス化中、-128 から 127 までの値は、整数オブジェクトにボックス化された後、再利用のためにメモリに保存されます。オブジェクトは常に 1 つだけです
。 –128 から 127 までの値を超えると、ボックス化された Integer オブジェクトは再利用されません。これは、ボックス化されるたびに新しい Integer オブジェクトを作成することと同じです。
上記の現象は、自動ボックス化の使用によって引き起こされます。自動ボックス化は使用しませんが、一般クラスと同様に new を使用してインスタンス化します。new が使用されるたびに新しいオブジェクトが作成されます。この自動ボックス化とボックス化解除は、基本的なデータ型だけでなく、String クラスでも使用されます。たとえば、よく String オブジェクトを宣言する場合:

String str = "sl"; 
//代替下面的声明方式 
String str = new String("sl");
ログイン後にコピー

基本データ (Primitive) 型のオートボックス化とアンボックス化 ボックス化 (アンボックス化) は、J2SE 5.0 から提供される機能です。基本的なデータ型をパッケージ化すると便利ですが、詳細が隠蔽されるため、基本的なデータ型とオブジェクトの違いを区別できる場合にのみ使用することをお勧めします。

オートボックス化とアンボックス化
Java では、処理されるほとんどすべてがオブジェクト (Object) です。たとえば、以前に使用したスキャナーもオブジェクトです。また、後で説明する文字列 (String) もオブジェクトです。ただし、基本的なデータ型はオブジェクトではありません。つまり、int、double、boolean などを使用して定義する変数や、直接書き込むリテラル定数です。
前のセクションでは、オブジェクト操作の便利さを大まかに見てきましたが、Java をしばらく使用したことがある人なら、基本的なデータ型をオブジェクトに変換する必要がある場合があることを知っています。たとえば、Map オブジェクトの put() メソッドを使用する場合、渡す必要があるパラメータは、基本データ型ではなくオブジェクトです。
基本データ型をオブジェクトにラップするには、ラッパー型 (ラッパー型) を使用する必要があることは、J2SE 5.0 より前では、次のステートメントを使用して Integer オブジェクトにラップする必要があることをすでに知っています: Integer integer = new Integer(10 );
自動ボックス化機能は、J2SE 5.0 以降で提供されます。次のステートメントを直接使用して、基本的なデータ型をパッケージ化できます。 . 自動ボクシングアクションを実行するかどうか。上記の例では、integer は Integer クラスのインスタンスを参照します。同じアクションを、boolean、byte、short、char、long、float、double などの基本データ型と、対応するラッパー型 (ラッパー型) Boolean、Byte、Short、Character、Long、Float、またはそれぞれDoubleが使用されます。オートボクシング関数を直接使用して、例 4.4 を書き換えてみましょう。

例 4.5 AutoBoxDemo.java

public class AutoBoxDemo { 
public static void main(String[] args) { 
Integer data1 = 10; 
Integer data2 = 20; 
// 转为double值再除以3 
System.out.println(data1.doubleValue() / 3); 
// 进行两个值的比较 
System.out.println(data1.compareTo(data2)); 
} 
}
ログイン後にコピー

このプログラムは、実行時に Integer のインスタンスとなり、オブジェクト操作を直接実行できるように見えます。結果は次のようになります:

3.3333333333333335

–1
自動ボックス化を使用する方法は次のようにすることもできます:

int i = 10; 
Integer integer = i;
ログイン後にコピー

より一般的な java.lang.Number クラスを使用して自動的にボックス化することもできます。例:

Numbernumber = 3.14f;

3.14f は、最初に Float として自動的にボックス化され、その後、number に割り当てられます。
J2SE 5.0 からは、自動ボックス化と自動アンボックス化が利用可能になりました。つまり、オブジェクト内の基本的なデータフォーム情報がオブジェクトから自動的に取り出されます。例えば、以下のように書くことが可能です。

Integer fooInteger = 10; 
int fooPrimitive = fooInteger;
ログイン後にコピー

Integerとして自動的にボックス化されるインスタンスをfooIntegerで参照した後、int型の変数fooPrimitiveに代入すると、自動的にint型になってfooPrimitiveに代入されます。動作中に、自動ボックス化およびボックス化解除も実行できます。例:

Integer i = 10; 
System.out.println(i + 10); 
System.out.println(i++);
ログイン後にコピー

上記の例では、20 と 10 が表示されます。コンパイラーは自動ボックス化とアンボックス化を自動的に実行します。つまり、10 が最初にボックス化され、次に i + 10 のときに最初にアンボックス化されます。 i++ 行も最初にボックスを解除してから、インクリメント操作を実行します。別の例を見てみましょう:

Boolean boo = true; 
System.out.println(boo && false);
ログイン後にコピー

同样的boo原来是Boolean的实例,在进行AND运算时,会先将boo拆箱,再与false进行AND运算,结果会显示false。
//////////////////////////////////////////////////////////////////
装箱:从基本类型转换成Object类型,称之为装箱;***拆箱:从Object转换乘基本类型的操作,称之为拆箱。 这个操作在反射过程中用的比较的多。
装箱:在堆中建立一个Object实例,把你指定的值复制成去;***拆箱:判别引用指向的堆中信息是否是要拆成的类型,是取出堆中值送给栈中变量,否则报异常
///////////////////////////////////////////////////////////////////
装箱是值类型到object类型或到该值类型所实现的任何接口类型的隐士转换。
将一个值类型装箱会分配一个对象实例并将该值复制到新的对象中。

int i=123; 
object o=i;
ログイン後にコピー

这句话的结果是在堆栈上创建一个对象o,而该对象在堆上引用int类型的值。该值是赋值给变量i
的值类型值的一个副本。
下面是显示执行装箱转换

int i=123; 
ojbect o=(object)i;
ログイン後にコピー

此例将整数变量i通过装箱转换为对象o。这样,存储在变量i中的值就从123改为456。此例显示对象保留了内容的原始副本。即123。
取消装箱是从object类型到值类型或从接口类型到实现该接口的值类型的显示转换。取消装箱操作包括:
检查对象实例,确保它是给定值类型的一个装箱值。
将该值从实例复制到值类型变量中。
例子:

int i=123; 
object box=i; 
int j=(int)box;
ログイン後にコピー

更多java自动装箱拆箱深入剖析相关文章请关注PHP中文网!

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート