猿问

关于泛型和反射的代码错误(cannot select from a type variable)

问题1:
想写个requestInfo的toString方法,把所有的成员变量都打印出来,子类就不用每次都写个toString方法了,但是父类怎么获取子类成员变量的值?

public class RequestInfo
{
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        Field[] fields = this.getClass().getDeclaredFields();
        for(Field field : fields)
        {
            sb.append(field.getName(), " = ", (这里怎么获取属性值?), ";");
        }
        return "";
    }
}

问题2
下面那个类P怎么实例化,也没懂错误的原因,用P.getClass()还是不行

public abstract class AbstractService<Q extends RequestInfo, P extends ResponseInfo>
{
    public static final Logger LOGGER = LoggerFactory.getLogger(AbstractService.class);

    private String logTag;

    private P respBean;

    public P execute(Q reqBean)
    {
        init();
        LOGGER.info(StringUtil.appendStr("Request : {}, req = {}", logTag, reqBean.toString()));

        try
        {
            if (checkInput(reqBean))
            {
                handle(reqBean, respBean);
            }
            else
            {
                throw new Exception(StringUtil.appendStr(logTag, " check input param invalid"));
            }
        }
        catch (Exception e)
        {
            LOGGER.error(StringUtil.appendStr(logTag, " Exception: "), e);
        }
        return respBean;
    }

    protected void init()
    {
        logTag = getClass().getSimpleName();
        respBean =P.class.newInsance();//这里报错,cannot select from a type variable
    }

    protected boolean checkInput(Q reqBean)
    {
        return true;
    }

    protected abstract void handle(Q reqBean, P respBean)
            throws Exception;
}
月关宝盒
浏览 3920回答 3
3回答

饮歌长啸

反射工具类 package cn.hylexus.app.util; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ReflectionUtils { public static List<Field> getFields(Class<?> clz) { List<Field> ret = new ArrayList<>(); for (Class<?> c = clz; c != Object.class; c = c.getSuperclass()) { Field[] fields = c.getDeclaredFields(); ret.addAll(Arrays.asList(fields)); } return ret; } /** * @param cls * 子类对应的Class * @param index * 子类继承父类时传入的索引,从0开始 * @return */ public static Class<?> getSuperClassGenericType(Class<?> cls, int index) { if (index < 0) return null; Type type = cls.getGenericSuperclass(); if (!(type instanceof ParameterizedType)) return null; ParameterizedType parameterizedType = (ParameterizedType) type; Type[] typeArguments = parameterizedType.getActualTypeArguments(); if (typeArguments == null || typeArguments.length == 0 || index > typeArguments.length - 1) return null; Type t = typeArguments[index]; if (!(t instanceof Class)) { return null; } return (Class<?>) t; } public static Class<?> getSuperClassGenericType(Class<?> cls) { return getSuperClassGenericType(cls, 0); } } 问题1 public class RequestInfo { @Override public String toString() { StringBuilder sb = new StringBuilder(); //可以拿到多层次基础的属性 List<Field> fields = ReflectionUtils.getFields(this.getClass()); for (Field f : fields) { f.setAccessible(true); try { sb.append(f.getName()).append("=").append(f.get(this)).append("\n"); } catch (Exception e) { e.printStackTrace(); } } return sb.toString(); } } 问题2 @SuppressWarnings("unchecked") protected void init() { logTag = getClass().getSimpleName(); try { //这里可以拿到动态绑定的Class信息 Class<?> clz = ReflectionUtils.getSuperClassGenericType(this.getClass(), 1); respBean = (P) clz.newInstance(); } catch (Exception e) { e.printStackTrace(); } }

BIG阳

第一个问题可以利用commons-beanutils做。
随时随地看视频慕课网APP

相关分类

Java
我要回答