はじめに
外部I/F へ入出力する際、共通処理したい場合などに「Object型」をつかうことがありますよね。
ラッパークラス(Byte,Boolean,Integer,Long..)、Collecion、Set、List型や Map型 等のすべてのオブジェクトクラスの祖先である、曖昧な型です。 代表的なクラスの系譜は以下のとおりです。
たまに、メソッドの引数にモードやフラグを用意してそれを判断して、Object型をキャストするような処理を書いているソースコードを見かけることがあります。
「不要な引数は増やさない。」ここではそのために Object の型を判定する処理について説明します。
java.lang.Object
↳ java.util.Collection (インターフェース)
↳ java.util.List (インターフェース)
↳ java.util.ArrayList
↳ java.util.LinkedList
↳ java.util.Set (インターフェース)
↳ java.util.HashSet
↳ java.util.TreeSet
↳ java.util.Map (インターフェース)
↳ java.util.HashMap
↳ java.util.TreeMap
↳ java.util.LinkedHashMap
判別方法
オブジェクトがListなのか、Mapなのか、文字列なのか、数値型なのか、その他なのかを判別するのには、「instanceof」を使います。
「instanceof」は、そのクラスまたはそのクラスを基底(ルーツ)にもつクラスかどうか判定する演算子です。
// 前提: Object obj は メソッドの引数設定時に アップキャストされてきたもの
if ( obj instanceof List ) {
// obj は List 型です
}
else if ( obj instanceof Collection ) {
// obj は List 型ではない(=事前の判定による) Collection 型です
// つまり、Set, HashSet, TreeSet などの集合体型です
}
else if( obj instanceof Map) {
// obj は Map 型です
}
上記に付け加えて必要になる判定ですが、オブジェクトが配列かどうかの判別するには、java.lang.Class型 の「
isArray()」を使います。
if( obj.getClass().isArray() ) {
// obj は 配列型です
}
最後に
紹介した方法で Object 型を判定することができるので、共通処理を作るのが便利。と思いますが、
必要以上に Object 型を使用しない ようにしてください。
冒頭で説明したとおり、このクラスは 曖昧 です。処理を呼び出す側次第で何色にでもなるので、リスクがあります。できる限りは 型を明確にするようにしましょう。
百聞は一見に如かず。お試しのソースを書いたので参考にして、自分のものにしてください。
お試しソース
import java.lang.reflect.Array;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.math.BigDecimal;
class objectTest {
public static void main(String args[]) {
//値のセット
String[] strList = new String[] {"String1","String2","String3","String4","String5"};
int[] intList = {2, 3, 5, 7, 9};
char[] chrList = {'C', 'H', 'A', 'R'};
List<Map<String,Object>> mapList1 = setTestData();
List<Map<Integer,Object>> mapList2 = setTestData2();
List<Object> mapList3 = setTestData3(mapList1, mapList2);
//値の判定と出力
anythingOutput(null);
anythingOutput("test");
anythingOutput(new BigDecimal(0.00003));
anythingOutput(strList);
anythingOutput(intList);
anythingOutput(chrList);
anythingOutput(mapList1);
anythingOutput(mapList2);
anythingOutput(mapList3);
}
/**
* 型判定出力
* @param obj オブジェクト型の値
* @return テストデータリスト
*/
private static void anythingOutput(Object obj) {
anythingOutput(obj, 0);
}
/**
* 型判定出力
* @param obj オブジェクト型の値
* @param intDept 階層
*/
private static void anythingOutput(Object obj, int intDept) {
System.out.print(blank(intDept));
if(obj == null) {
System.out.print("[null]");
} else if(obj.getClass().isArray()) {
//オブジェクトが配列の場合
int len = Array.getLength(obj);
System.out.print("[Array] value= {\n");
for(int i=0; i < len; i++) {
//配列の件数分、再帰的な処理を行う
anythingOutput(Array.get(obj, i), intDept + 1);
}
System.out.print(blank(intDept) + "}");
} else if(obj instanceof Collection<?>) {
//オブジェクトがコレクション型の場合
Collection<?> list = (Collection<?>)obj;
System.out.print("[Collection] value= {\n");
for(Object row : list) {
//リストの件数分、再帰的な処理を行う
anythingOutput(row, intDept + 1);
}
System.out.print(blank(intDept) + "}");
} else {
//オブジェクトがコレクション型でない場合
if(obj instanceof Map) {
//Mapの場合
Map<?,?> map = (Map<?,?>) obj;
System.out.print("[Map] value={\n");
Iterator<?> keyItr = map.keySet().iterator();
Object key = null;
while(keyItr.hasNext()) {
//キーが取得できる場合、出力
key = keyItr.next();
anythingOutput(key, intDept + 1);
System.out.print(blank(intDept + 1) + " : ");
anythingOutput(map.get(key), 0);
}
System.out.print(blank(intDept) + "}");
} else if(obj instanceof String) {
//文字列の場合
System.out.print("["+ obj.getClass().getName() +"] value=\"" + (String)obj + "\"");
} else if(obj instanceof Number) {
//数値の場合
System.out.print("["+ obj.getClass().getName() +"] value=\"" + ((Number)obj).toString() + "\"");
} else {
//その他の場合(toStringはObjectのメソッド)
System.out.print("["+ obj.getClass().getName() +"] value=\"" + obj.toString() + "\"");
}
}
System.out.print("\n");
return;
}
/**
* テストデータの設定
* @return テストデータリスト
*/
public static List<Map<String,Object>> setTestData() {
//オブジェクトの初期化
List<Map<String,Object>> mapList = new ArrayList<Map<String,Object>>();
Map<String, Object> map = null;
//10件分のテストデータを作成する
for(int i = 0; i < 10; i++) {
map = new HashMap<String, Object>();
//キー名(String)、キー値(Integer)
map.put("keyCd", Long.valueOf(i + 1));
//属性名(String)、属性値(String)
map.put("text", (new String(Character.toChars(65+i)).concat(String.valueOf(i+1))) );
mapList.add(map);
}
return mapList;
}
/**
* テストデータの設定
* @return テストデータリスト2
*/
public static List<Map<Integer, Object>> setTestData2() {
//オブジェクトの初期化
List<Map<Integer,Object>> mapList = new ArrayList<Map<Integer,Object>>();
Map<Integer, Object> map = null;
//10件分のテストデータを作成する
for(int i = 0; i < 10; i++) {
map = new HashMap<Integer, Object>();
map.put(Integer.valueOf(1), (i + 1));
map.put(Integer.valueOf(2), (new String(Character.toChars(65+i)).concat(String.valueOf(i+1))) );
mapList.add(map);
}
return mapList;
}
/**
* テストデータの設定
* @return テストデータリスト3(Listの子にListがある)
*/
public static List<Object> setTestData3(Object objList1, Object objList2) {
//オブジェクトのマージ
List<Object> newList = new ArrayList<Object>();
newList.add(objList1);
newList.add(objList2);
newList.add("test3");
newList.add(Long.valueOf(4));
newList.add(null);
return newList;
}
/**
* 空白文字返却
* @param 空白文字繰り返し回数
* @return 空白文字列
*/
private static String blank(int intRepeat) {
String strBlank = "";
for(int i = 0; i < intRepeat; i++) {
strBlank = strBlank.concat(" ");
}
return strBlank;
}
}

