如何使用反射从代码段

时间:2017-10-05 12:27:27

标签: java reflection

我需要记录每个对象的值。对象的类型可能每次都有所不同,我试图使用反射来调用类的getter。但是我被困在一个我需要重新调用readData方法的地方,如果class是一个自定义对象。如何让对象在下面的else块中传入readData(obj)。

private static void readData(Object resp) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    Method[] allMethods = resp.getClass().getDeclaredMethods();
    for (Method m : allMethods) {
        if ("get".equalsIgnoreCase(m.getName().substring(0, 3))) {
            Class<?> type = m.getReturnType();
            if (isWrapperType(type) || type.isPrimitive()) {
                System.out.println(m.invoke(resp)) ;
            }
            else if(Collection.class.isAssignableFrom(type)) {
                if(m.getGenericReturnType() instanceof ParameterizedType){
                    ParameterizedType paramType = (ParameterizedType) m.getGenericReturnType();
                    System.out.println("List is of type "+(Class<?>) paramType.getActualTypeArguments()[0]);
                }
                //iterate the object and recall read data with generic type of collection

            }
            else{
                //Problem : need to pass object from type, how do i get this class object, as it should not be any new instance
                readData(obj);
            }

        }

    }

}
private static final Set<Class<?>> WRAPPER_TYPES = getWrapperTypes();

public static boolean isWrapperType(Class<?> clazz)
{
    return WRAPPER_TYPES.contains(clazz);
}

private static Set<Class<?>> getWrapperTypes()
{
    Set<Class<?>> ret = new HashSet<Class<?>>();
    ret.add(Boolean.class);
    ret.add(Character.class);
    ret.add(Byte.class);
    ret.add(Short.class);
    ret.add(Integer.class);
    ret.add(Long.class);
    ret.add(Float.class);
    ret.add(Double.class);
    ret.add(String.class);
    ret.add(BigDecimal.class);
    ret.add(Number.class);
    return ret;
}

这就是BO的样子

Response.java

public class Response {
    List<OrderStatusList> orderStatusList;
    StatusResponse        response;

    //getter-setter
}

StatusResponse.java

public class StatusResponse {
    protected String type;
    protected String message;

    // getter-setter
}

OrderStatusList.java

public class OrderStatusList {
    Header header;
    // getter - setter
}

Header.java

public class Header {
    protected String orderNumber;
    protected String orderStatus;
    protected List<DtOrderStatusResponseList> item;

    //getter-setter
}

DtOrderStatusResponseList.java

public class DtOrderStatusResponseList {
    protected String orderItemNumber;
    protected String orderItemMaterialNumber;
    protected String orderItemRequestedQuantity;
    protected String orderItemStatus;

    //getter-setter
}

2 个答案:

答案 0 :(得分:0)

因为您只需要记录值而不使用它们在所有包含所需信息的类中覆盖Object#toString方法。 使用这种方法,您可以有效地将每个对象的信息放在一行中。

例如

public class SOFTest {
    privat int age, weight, height;
    private Header header;

    //Constructor etc.

    @Overwrite
    public String toString() {
        return "SOFTest(" + String.format("%s, %s, %s %s)", age, weight, height, header.toString()));
    }
}

答案 1 :(得分:0)

我需要在readData()中调用getter到自定义类的对象,所以传递method.invoke(resp)。它会是这样的:

private static void readData(Object resp) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method[] allMethods = resp.getClass().getDeclaredMethods();
for (Method m : allMethods) {
    if ("get".equalsIgnoreCase(m.getName().substring(0, 3))) {
        Class<?> type = m.getReturnType();
        if (isWrapperType(type) || type.isPrimitive()) {
            System.out.println(m.invoke(resp)) ;
        }
        else if(Collection.class.isAssignableFrom(type)) {
            if(m.getGenericReturnType() instanceof ParameterizedType){
                ParameterizedType paramType = (ParameterizedType) m.getGenericReturnType();
                System.out.println("List is of type "+(Class<?>) paramType.getActualTypeArguments()[0]);
            }
        }
        else{
            //Solution : need to invoke the getter to get the object and it would work
            readData(method.invoke(resp));
        }

    }
  }
}