Java泛型类型T如何调用getValue、setValue等get/set通用方法
可行实现方案
方案1:传入函数式接口封装get/set逻辑(无侵入,推荐)
不需要修改原有实体类的代码,直接在调用方法时传入对应属性的getter、setter函数即可,完美适配无继承关系的多类场景:
// 泛型方法增加4个参数,分别对应value的get、set,codeListId的get、set private <T> T checkBusinessEntityTypeCode(CheckDtKdt checkDtKdt, T kdtCode, T dtCode, Function<T, String> getValue, BiConsumer<T, String> setValue, Function<T, String> getCodeListId, BiConsumer<T, String> setCodeListId) { if (kdtCode != null && dtCode != null) { String kdtValue = getValue.apply(kdtCode); String dtValue = getValue.apply(dtCode); if (StringUtils.compare(kdtValue, dtValue) != 0) { checkFieldsDtKdtService.save14Graph(checkDtKdt, dtValue, kdtValue); setValue.accept(dtCode, kdtValue); } String kdtCodeListId = getCodeListId.apply(kdtCode); String dtCodeListId = getCodeListId.apply(dtCode); if (StringUtils.compare(kdtCodeListId, dtCodeListId) != 0) { checkFieldsDtKdtService.save14Graph(checkDtKdt, dtCodeListId, kdtCodeListId); setCodeListId.accept(dtCode, kdtCodeListId); } } return dtCode; }
调用时直接传入对应类的方法引用即可:
// 示例:入参为TypeA类对象 checkBusinessEntityTypeCode(checkDtKdt, typeAKdt, typeADt, TypeA::getValue, TypeA::setValue, TypeA::getCodeListId, TypeA::setCodeListId); // 示例:入参为TypeB类对象 checkBusinessEntityTypeCode(checkDtKdt, typeBKdt, typeBDt, TypeB::getValue, TypeB::setValue, TypeB::getCodeListId, TypeB::setCodeListId);
注:该方案需要JDK 1.8及以上版本支持,编译期即可校验方法正确性,无额外性能损耗和安全风险
方案2:抽取公共接口(适合可修改原有类的场景)
如果有权限调整所有入参类的代码,可以先定义公共接口:
public interface CodeEntity { String getValue(); void setValue(String value); String getCodeListId(); void setCodeListId(String codeListId); }
让所有需要用到该方法的实体类实现这个接口,之后给泛型加上上限约束即可直接调用原有逻辑:
private <T extends CodeEntity> T checkBusinessEntityTypeCode(CheckDtKdt checkDtKdt, T kdtCode, T dtCode) { if (kdtCode != null && dtCode != null) { if (StringUtils.compare(kdtCode.getValue(), dtCode.getValue()) != 0) { checkFieldsDtKdtService.save14Graph(checkDtKdt, dtCode.getValue(), kdtCode.getValue()); dtCode.setValue(kdtCode.getValue()); } if (StringUtils.compare(kdtCode.getCodeListId(), dtCode.getCodeListId()) != 0) { checkFieldsDtKdtService.save14Graph(checkDtKdt, dtCode.getCodeListId(), kdtCode.getCodeListId()); dtCode.setCodeListId(kdtCode.getCodeListId()); } } return dtCode; }
不推荐方案:反射
也可以通过反射调用get/set方法,但存在性能损耗、编译期无法校验方法存在性、运行时易报错的问题,非特殊情况不建议使用。
内容的提问来源于stack exchange,提问作者Vitaliy
相关产品推荐
相关产品推荐

