2005.11.15 株式会社四次元データ CTO 畠中晃弘
3.3. メソッドの呼び出し
メソッドの呼び出しの際にも、ボクシング・アンボクシングが行われます。たとえば、int を引数とするメソッドの引数に Integer の参照を使用することができます。
public void methodA(int i) { ....... } public static void main (String[] args) { methodA(new Interger(100)); }
呼び出すメソッドを決定するためには、まずボクシング・アンボクシングを行わずにシグネチャが一致するメソッドが検索されます。ボクシング・アンボクシングよりも、プリミティブ型の暗黙的な型変換(ワイドニング変換)のほうが優先されます。全体的にいえることですが、J2SE1.4 までのプログラムの動作は原則的に変更されないよう言語仕様が定められています(もし以下の例で methodB(Short)が呼び出されてしまったら、J2SE1.4とJ2SE5.0で呼び出されるメソッドが異なることになってしまいます)。
public void methodB(int i) { ....... } public void methodB(Short s) { ....... } public static void main (String[] args) { short s = 100; methodB(s); // methodB(int i) が呼び出される }
ボクシング・アンボクシングを行うことにより適用可能なメソッドが複数存在する場合は、コンパイルエラーとなります。
public void methodC(int i, long l) { ....... } public void methodC(Integer a, Long l) { ....... } public static void main (String[] args) { methodC(100, new Long(100)); // コンパイルエラー }
3.4. インスタンスの共用
ボクシングが行われる際、毎回新しいインスタンスが作成されるわけではありません。特定の型のある範囲の値に対応するインスタンスは必ず同じものが共用されます。その特定の型、値の範囲は以下の通りです。
- char 型の \u0000〜\u007F
- short 型の -128〜127
- int 型の -128〜127
つまり、以下のようになります。
Integer a = 100; Integer b = 100; // a と b は同じインスタンスへの参照。つまり (a == b) は true である。 Integer c = 10000; Integer d = 10000; // c と d は別のインスタンスへの参照。つまり (c == d) は false である(※)。
J2SE5.0 ではラッパークラスすべてに static な valueOf メソッドが追加されました(J2SE1.4までは Boolean クラスにのみ定義されていました)。これはプリミティブ型の値から対応するオブジェクトを取得するメソッドです。このメソッドでも、上記の範囲の値は同じ値に対しては常に同じインスタンスが返されます。
Integer a = Integer.valueOf(100); Integer b = Integer.valueOf(100); // a と b は同じインスタンスへの参照。つまり (a == b) は true である。 Integer c = Integer.valueOf(10000); Integer d = Integer.valueOf(10000); // c と d は別のインスタンスへの参照。つまり (c == d) は false である(※)。
※ 特定の範囲外の数値が必ず別のオブジェクトにアンボクシングされることは保証されていません。最適化されたコンパイラでこの結果が true になるケースがあるかもしれません。
(実習課題)
ランダムに生成した 1000 個の double 値をいったん ArrayList<Double> 型コレクションに登録し、そのコレクションから値をすべて取り出して全数の平均値および総和を表示するプログラムを作成しなさい。