利用java反射纵深获取对象的属性值

说明:

  1. 所谓纵深:对象的属性的属性的属性......的属性(兼容List类型属性)。
  2. 尽管功能上已经大致实现,然则代码过烂(直面惨淡),望各位有志之士加以重构。别忘了重构后传给俺一份。
  3. 代码实现依赖spring-core-4.3.16.RELEASE.jar(版本或可不一致)

代码:

java bean:

package com.example.demo.bean;

import java.util.List;

public class PolicyDetail {
	private String policyNo;
	private List<Insurant> insurants;
	private Applicant applicant;

	public Applicant getApplicant() {
		return applicant;
	}

	public void setApplicant(Applicant applicant) {
		this.applicant = applicant;
	}

	public String getPolicyNo() {
		return policyNo;
	}

	public void setPolicyNo(String policyNo) {
		this.policyNo = policyNo;
	}

	public List<Insurant> getInsurants() {
		return insurants;
	}

	public void setInsurants(List<Insurant> insurants) {
		this.insurants = insurants;
	}

}
package com.example.demo.bean;

public class Applicant {
	private String name;

	public Applicant(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
package com.example.demo.bean;

import java.util.List;

public class Insurant {
	private String customerno;
	private List<RiskInfo> riskInfos;
	
	public Insurant(String customerno, List<RiskInfo> riskInfos) {
		super();
		this.customerno = customerno;
		this.riskInfos = riskInfos;
	}
	public String getCustomerno() {
		return customerno;
	}
	public void setCustomerno(String customerno) {
		this.customerno = customerno;
	}
	public List<RiskInfo> getRiskInfos() {
		return riskInfos;
	}
	public void setRiskInfos(List<RiskInfo> riskInfos) {
		this.riskInfos = riskInfos;
	}
	
}
package com.example.demo.bean;

import java.util.List;

public class RiskInfo {
	private String riskCode;
	private List<DutyInfo>  dutyInfos;
	
	public RiskInfo(String riskCode, List<DutyInfo> dutyInfos) {
		super();
		this.riskCode = riskCode;
		this.dutyInfos = dutyInfos;
	}
	public String getRiskCode() {
		return riskCode;
	}
	public void setRiskCode(String riskCode) {
		this.riskCode = riskCode;
	}
	public List<DutyInfo> getDutyInfos() {
		return dutyInfos;
	}
	public void setDutyInfos(List<DutyInfo> dutyInfos) {
		this.dutyInfos = dutyInfos;
	}
	
}
package com.example.demo.bean;

public class DutyInfo {
	private String dutyCode;
	private String dutyName;
	private String dutyAmnt;
	
	public DutyInfo(String dutyCode, String dutyName, String dutyAmnt) {
		super();
		this.dutyCode = dutyCode;
		this.dutyName = dutyName;
		this.dutyAmnt = dutyAmnt;
	}
	public String getDutyCode() {
		return dutyCode;
	}
	public void setDutyCode(String dutyCode) {
		this.dutyCode = dutyCode;
	}
	public String getDutyName() {
		return dutyName;
	}
	public void setDutyName(String dutyName) {
		this.dutyName = dutyName;
	}
	public String getDutyAmnt() {
		return dutyAmnt;
	}
	public void setDutyAmnt(String dutyAmnt) {
		this.dutyAmnt = dutyAmnt;
	}
	
}
package com.example.demo.bean;

public class FieldInfo {
	/**
	 * 属性名
	 */
	private String fieldName;
	/**
	 * 对应关系值
	 */
	private String idString;
	/**
	 * 对应关系字段
	 */
	private String idFieldName;
	
	
	
	public FieldInfo(String fieldName, String idString, String idFieldName) {
		super();
		this.fieldName = fieldName;
		this.idString = idString;
		this.idFieldName = idFieldName;
	}
	
	public String getIdFieldName() {
		return idFieldName;
	}

	public void setIdFieldName(String idFieldName) {
		this.idFieldName = idFieldName;
	}

	public String getFieldName() {
		return fieldName;
	}
	public void setFieldName(String fieldName) {
		this.fieldName = fieldName;
	}
	public String getIdString() {
		return idString;
	}
	public void setIdString(String idString) {
		this.idString = idString;
	}
	
}

function:

package com.example.demo.service;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import org.springframework.util.ReflectionUtils;

import com.example.demo.bean.Applicant;
import com.example.demo.bean.DutyInfo;
import com.example.demo.bean.FieldInfo;
import com.example.demo.bean.Insurant;
import com.example.demo.bean.PolicyDetail;
import com.example.demo.bean.RiskInfo;

public class TestReflection {
	public static void main(String[] args) {
		// 准备测试数据
		PolicyDetail policyDetail = createPolicyDetail();
		// applicant为policyDetail中的属性 name为Applicant中的属性 测试非List获取值
		String elementFrom1 = "applicant-name";
		// 测试获取List属性中的值
		String elementFrom = "insurants[customerno]-riskInfos[riskCode]-dutyInfos[dutyCode]-dutyName";
		// FieldInfo中的对应值对应关系字段 以便对应到List中的某个元素
		Insurant insurant = policyDetail.getInsurants().get(1);
		RiskInfo riskInfo = insurant.getRiskInfos().get(0);
		DutyInfo dutyInfo = riskInfo.getDutyInfos().get(0);
		// 将字符串转换成FieldInfo列表 方便随后处理
		List<FieldInfo> fieldInfos = String2FieldInfo(elementFrom);
		List<FieldInfo> fieldInfos1 = String2FieldInfo(elementFrom1);

		// 打印出两个测试获取到的值
		System.out.println(getReflectionValues(policyDetail, fieldInfos1));
		System.out.println(getReflectionValues(policyDetail, fieldInfos, insurant, riskInfo, dutyInfo));
	}

	/**
	 * 准备测试数据
	 * 
	 * @return
	 */
	public static PolicyDetail createPolicyDetail() {
		PolicyDetail policyDetail = new PolicyDetail();
		Insurant insurant = new Insurant("100",
				Arrays.asList(new RiskInfo("321", Arrays.asList(new DutyInfo("321110", "321110的名称", "20000")))));
		Insurant insurant1 = new Insurant("200",
				Arrays.asList(new RiskInfo("321", Arrays.asList(new DutyInfo("321111", "321111的名称", "20000")))));
		policyDetail.setInsurants(Arrays.asList(insurant, insurant1));
		policyDetail.setPolicyNo("123456");
		policyDetail.setApplicant(new Applicant("sdk"));
		return policyDetail;
	}

	/**
	 * 将属性值来源字符串转换成List<FieldInfo>
	 * 
	 * @param elementFrom
	 * @return
	 */
	private static List<FieldInfo> String2FieldInfo(String elementFrom) {
		String[] elements = elementFrom.split("-");
		return Arrays.asList(elements).stream().map(e -> {
			// 如果沒有中括号
			if (e.contains("[")) {
				return new FieldInfo(e.substring(0, e.indexOf("[")), "",
						e.substring(e.indexOf("[") + 1, e.indexOf("]")));
			} else {
				return new FieldInfo(e, "", "");
			}

		}).collect(Collectors.toList());
	}

	/**
	 * 
	 * @param valueFrom
	 *            最外层对象
	 * @param fieldInfos
	 *            将要获取值的属性
	 * @param args
	 *            如果从List类型的属性中获取某个元素某个属性的值时 将用来对应到List中的哪个元素
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	private static String getReflectionValues(Object valueFrom, List<FieldInfo> fieldInfos, Object... args) {
		for (int i = 0; i < args.length; i++) {
			Object arg = args[i];
			if (Objects.isNull(arg)) {
				return "";
			}
		}
		// 获取前边属性的值 并作为值的来源 获取下一个属性的值
		Object objReturn = null;
		for (int i = 0; i < fieldInfos.size(); i++) {
			FieldInfo fieldInfo = fieldInfos.get(i);
			valueFrom = getReflectionValue(valueFrom, fieldInfo.getFieldName());
			if (valueFrom instanceof List) {// 如果返回值是个list 则获取根据List id获取对应的对象
				for (int j = 0; j < ((List) valueFrom).size(); j++) {
					Object curr = ((List) valueFrom).get(j);
					boolean isBreak = false;
					for (int k = 0; k < args.length; k++) {
						Object object = args[k];
						if (object.getClass().getName().equals(curr.getClass().getName())) {
							String idString = (String) getReflectionValue(curr, fieldInfo.getIdFieldName());
							if (Objects.equals(idString, getReflectionValue(args[k], fieldInfo.getIdFieldName()))) {
								valueFrom = curr;
								isBreak = true;
								break;
							}
						}
					}
					if (isBreak) {
						break;
					}

				}
			} else {
				objReturn = valueFrom;
			}
		}
		return String.valueOf(objReturn);
	}

	/**
	 * 获取单个属性的值
	 * 
	 * @param valueFrom
	 * @param fieldName
	 * @return
	 */
	private static Object getReflectionValue(Object valueFrom, String fieldName) {
		Field field = ReflectionUtils.findField(valueFrom.getClass(), fieldName);
		ReflectionUtils.makeAccessible(field);
		return ReflectionUtils.getField(field, valueFrom);
	}

}

输出后的结果为:

sdk
321111的名称

结束语:

多多指教哦!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值