■ リフレクション(Reflection) Java

○ リフレクションとは?
・Javaクラスからフィールドやメソッドなどの情報を取得するAPI
・取得したメソッドを実行することも可能
・java.lang.Classやjava.lang.reflect.*を参照

○ リフレクションは、奥が深く、また応用範囲も広いが、以下の例を示す

例-0:



  /**
   * 指定されたクラスのデフォルトコンストラクタを取得する
   * @param clazz
   * @return
   */
  public static Constructor getDefaultConstructor(Class clazz) {
    Constructor[] constructors = clazz.getConstructors();
    for (Constructor cons : constructors) {
        Class[] params = cons.getParameterTypes();
        if (params.length == 0) {
          return cons;
        }
    }
    return null;
  }



例-1:



  /**
   * 指定されたクラスのフィールドの定義情報を取得する.
   * @param clazz
   * @return
   */
  public static Map<String,FieldInfo> getFieldDefList(Class clazz) {
    Map<String,FieldInfo> fields = new HashMap<String,FieldInfo>();
    Field[] javaFields = clazz.getDeclaredFields();
    for (Field javaField : javaFields) {
      FieldInfo fieldInfo = new FieldInfo();
      String fieldName = javaField.getName();
      fieldInfo.setJavaField(javaField);
      fields.put(fieldName, fieldInfo);
    }
    return fields;
  }



例-2;



  /**
   * Staticメソッドをinvokeする<br>
   * 同じ名前のメソッド名は一つしかないことが前提.
   * @param className
   * @param methodName
   * @return
   * @throws InvocationTargetException
   * @throws IllegalAccessException
   * @throws IllegalArgumentException
   * @throws ClassNotFoundException
   */
  public static Object invoke(String className,String methodName,Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassNotFoundException {
    Class clazz = Class.forName(className);
    Method[] methods = clazz.getMethods();
    for (Method method : methods) {
      if (methodName.equals(method.getName())) {
        return method.invoke(null, args);
      }
    }
    return null;
  }



例-3:



  /**
   * オブジェクトをMapに変換する
   * @param obj
   * @return
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static Map<String,String> convertToMap(Object obj) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
    Map<String,FieldInfo> fieldDefs = getFieldDefList(obj.getClass());
    Map<String,String> map = new HashMap<String,String>();
    Iterator<String> fieldNames = fieldDefs.keySet().iterator();
    while (fieldNames.hasNext()) {
      String name = fieldNames.next();
      String methodName = StrUtil.getterName(name);
      Method method = getMethod(obj.getClass(), methodName);
      String value = method.invoke(obj, new Object[]{})+"";
      map.put(name, value);
    }
    return map;
  }