为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

月关宝盒 2019-02-17 12:43:04
问题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; }
查看完整描述

3 回答

?
饮歌长啸

TA贡献1951条经验 获得超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();
        }
    }
查看完整回答
反对 回复 2019-03-01
?
BIG阳

TA贡献1859条经验 获得超6个赞

第一个问题可以利用commons-beanutils做。

查看完整回答
反对 回复 2019-03-01
  • 3 回答
  • 0 关注
  • 3919 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信