【概要】
Autoboxing は便利な機能である。
だが、実際の挙動を表すコードが隠れてしまう分、意外なところで問題が発生したりして注意が必要である。例えば私が最近見た例だと、次のようなものがある。
Autoboxing は便利な機能である。
だが、実際の挙動を表すコードが隠れてしまう分、意外なところで問題が発生したりして注意が必要である。例えば私が最近見た例だと、次のようなものがある。
【詳細】
このソースで定義されている DataContainer はもともとは JDK1.4 用に作られていたもので、オリジナルのソースではシグニチャがプリミティブタイプではなく、Integer や Boolean になっていた。import java.util.*; public class DataContainer { private final Map dataMap = new HashMap(); public void put(String key, Object value) { dataMap.put(key, value); } public boolean getBooleanValue(String key) { return (Boolean) dataMap.get(key); } public int getIntegerValue(String key) { return (Integer) dataMap.get(key); } public static void main(String[] args) { DataContainer dataContainer = new DataContainer(); dataContainer.put("key1", Boolean.valueOf(true)); dataContainer.put("key2", Integer.valueOf(5)); // 登録されているデータを取得 boolean value1 = dataContainer.getBooleanValue("key1"); int value2 = dataContainer.getIntegerValue("key2"); // 登録されていないデータを取得 int value3 = dataContainer.getIntegerValue("key3"); // NullPointerException } }
このソースを担当者がリファクタリングしていく課程で、開発環境が JDK 5.0 に移行したため、Autoboxing に対応させて上のように書き換えたものである。
Unboxing が使われているため、このソースだと getBoolean() の中で Boolean#booleanValue() が呼び出されていることや、getIntegerValue() の中で Integer#intValue() が呼び出されていることに気づきにくくなってしまっている。
この手の「隠された挙動」による例外の発生には要注意である。
コメント