Go to Contents Go to Java Page
J2SE 1.5 虎の穴
 
 

Autoboxing/Auto-Unboxing

 
 
Tiger こりゃ、便利
 
 

私はひそかに JSR-201 の中で、1 番簡単に使えてかつ 1 番便利なのが Autoboxing だと思っています。ここで書いている時点でひそかでも何でもないですが...

なにはともあれ、便利です。

何をやってくるかというと、プリミティブとそのラッパークラス間の変換を自動でやってくるのです。どういうことかというと、こんなことです。

    int ten = new Integer(10);
    Integer nine = ten - 1;

こんなことができたらすごいと思いません ?

ちなみに Autoboxing が プリミティブ -> ラッパ の自動変換、Auto-Unboxing が ラッパ -> プリミティブの自動変換のことです。

 

 
 
Tiger それじゃどこで使うか
 
 

何といわれようが、コレクションです。

コレクションは便利なのですが、プリミティブ型の値を保持することはできません。その代わりにラッパを使用するのはご存知の通り。

    List<Integer> list = new ArrayList<Integer>();
    list.add(new Integer(10));

これが Autoboxing を使えば、次のように書けます。

    List<Integer> list = new ArrayList<Integer>();
    list.add(10);

プリミティブな値を直接コレクションに add しているように見えますが、実際は Autoboxing によって Integer オブジェクトに変換されます。

それでも、格段に楽になると思いませんか。

気をつけなくてはいけないのは、例えば List#remove メソッドのように引数が int と Object のものがあるばあい、引数が int だったら Autoboxing はされません。当たり前ですね。

    List list = new ArrayList();
        ...
    list.add(10);
        ...
    list.remove(10); // Integer(10) が削除されずに、10 番目の要素が削除される

メソッドの引数だけでなく戻り値もちゃんと変換してくれます。

public class AutoboxingSample2 {
    public Integer foo(int x) {
        return new Integer(x);
    }
 
    public int bar(Integer y) {
        return y.intValue();
    }
 
    public AutoboxingSample2() {
        Integer x = foo(new Integer(10));
        int y = bar(10);
 
        // これも OK
        int z = foo(new Integer(10));
        Integer w = bar(10);
    }
  
    public static void main(String[] args) {
        new AutoboxingSample2();
    }
}

もちろん、ラッパとプリミティブを直接代入することもできます。

public class AutoboxingSample3 {
    public AutoboxingSample3() {
        int x = new Integer(10);
        Integer y = 5;
 
        // これも OK
        x = y;
        y = x;
    }
 
    public static void main(String[] args) {
        new AutoboxingSample3();
    }
}

これでラッパとプリミティブを意識することなしに使用することができます。

 
 
Tiger 大体の想像はつくけれど
 
 

コンパイラがどのように解釈しているかは大体分かりますね。それでも一応逆コンパイラの Jad を使って確かめてみましょう。

逆コンパイルしたのは先ほどのサンプル Autoboxing3 クラスです。これを Jad で逆コンパイルすると

public class AutoboxingSample3
{
 
    public AutoboxingSample3()
    {
        int i = (new Integer(10)).intValue();
        Integer integer = Integer.valueOf(5);
        i = integer.intValue();
        integer = Integer.valueOf(i);
    }
 
    public static void main(String args[])
    {
        new AutoboxingSample3();
    }
}

Integer を int に変換するときには Integer#intValue メソッドを使用し、int から Integer に変換するときには Integer.valueOf メソッドが使われていることが分かります。

すなわち、見た目はラッパとプリミティブを区別なく使用できたとしても、パフォーマンス的には今までと何も変わらないということです。

逆にいえば、プリミティブとラッパを意識しないぶん、Autoboxing を知らずに使うとパフォーマンスダウンの原因になりうるということです。なにごともやりすぎはよくないということですね。

 

 
 
Tiger おわりに
 
 

Autoboxing は簡単だけども、使える機能です。

コレクションでいちいちラッパオブジェクトを生成することだけでも得をした気分になるものです ^^;;

でも、使いすぎには注意しましょう。

 

今回使用したサンプルはここからダウンロードできます。

参考

(Dec. 2003)
(改訂 Jan. 2004)

 
 
Go to Contents Go to Java Page