短そうな方法でラッパー型とプリミティブ型の相互変換
概要
今日は、ラッパー型のClassオブジェクトとプリミティブ型のClassオブジェクトを相互に変換してみます。
ラッパー→プリミティブ
staticフィールドであるInteger.TYPE はint.classを返します。
他のラッパークラスにも同名のフィールドがあるので、リフレクションでstaticなTYPEフィールドを取り出せばよいとわかります。
プリミティブ→ラッパー
先日のエントリ
変数のデフォルト値(主にプリミティブの)取得の抽象化
の方法でラッパーインスタンスが1つ取得できるので、getClass()をすればラッパー型が取得できます。
ただしこの方法ではvoid.classからVoid.classは取得できません。
コード
package test; import java.lang.reflect.Array; public class WrapperToPrimitive { @SuppressWarnings("unchecked") public static <T> Class<T> wrapperToPrimitive(final Class<T> wrapClass) { Class<T> result; try { result = (Class<T>) wrapClass.getField("TYPE").get(null); } catch (Exception e) { throw new IllegalArgumentException(e); } if(!result.isPrimitive()) { throw new IllegalArgumentException("not wrapper: " + wrapClass); } return result; } @SuppressWarnings("unchecked") public static <T> Class<T> primitiveToWrapper(final Class<T> primClass) { return (Class<T>) Array.get(Array.newInstance(primClass, 1), 0).getClass(); } public static void main(final String[] args) { System.out.println(wrapperToPrimitive(Boolean.class)); System.out.println(wrapperToPrimitive(Byte.class)); System.out.println(wrapperToPrimitive(Short.class)); System.out.println(wrapperToPrimitive(Integer.class)); System.out.println(wrapperToPrimitive(Long.class)); System.out.println(wrapperToPrimitive(Float.class)); System.out.println(wrapperToPrimitive(Double.class)); System.out.println(wrapperToPrimitive(Character.class)); System.out.println(wrapperToPrimitive(Void.class)); System.out.println(primitiveToWrapper(boolean.class)); System.out.println(primitiveToWrapper(byte.class)); System.out.println(primitiveToWrapper(short.class)); System.out.println(primitiveToWrapper(int.class)); System.out.println(primitiveToWrapper(long.class)); System.out.println(primitiveToWrapper(float.class)); System.out.println(primitiveToWrapper(double.class)); System.out.println(primitiveToWrapper(char.class)); // System.out.println(primitiveToWrapper(void.class)); // 型付き Class<Integer> prim = wrapperToPrimitive(Integer.class); Class<Integer> wrap = primitiveToWrapper(int.class); } }
実行結果
boolean byte short int long float double char void class java.lang.Boolean class java.lang.Byte class java.lang.Short class java.lang.Integer class java.lang.Long class java.lang.Float class java.lang.Double class java.lang.Character
ライブラリ
ところで、こういう便利そうなものはすべからくライブラリが用意されています。
当然ですが、本エントリのような遅そうな実装にはなっておらず、条件分岐で実装されていると思います。
http://commons.apache.org/lang/api/org/apache/commons/lang3/ClassUtils.html#wrapperToPrimitive(java.lang.Class)
http://commons.apache.org/lang/api/org/apache/commons/lang3/ClassUtils.html#primitiveToWrapper(java.lang.Class)
ただ、戻り値に型パラメータがついていた方が便利ではないでしょうか。