一、什么是反射
反射就是把Java类中的各个成分映射成一个个的Java对象。即在运行状态中,对于任意一个类,都能够知道这个类的所以属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性。这种动态获取信息及动态调用对象方法的功能叫Java的反射机制。
1. 反射机制的功能
Java反射机制主要提供了以下功能:
- 在运行时判断任意一个对象所属的类。
- 在运行时构造任意一个类的对象。
- 在运行时判断任意一个类所具有的成员变量和方法。
- 在运行时调用任意一个对象的方法。
- 生成动态代理。
2. 实现反射机制的类
Java中主要由以下的类来实现Java反射机制(这些类都位于java.lang.reflect包中):
-
Class类:代表一个类。 Field类:代表类的成员变量(成员变量也称为类的属性)。
-
Method类:代表类的方法。
-
Constructor类:代表类的构造方法。
-
Array类:提供了动态创建数组,以及访问数组的元素的静态方法。
二、反射的使用
下面分步说明以下如何通过反射获取我们需要的内容。
我们先随意写一个Customer类(就是一个PO类),然后看看如何通过反射对这个类进行操作。
public class BeanUtils { private BeanUtils() { } public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target) { return copyListProperties(sources, target, null); } /** * @author Johnson * 使用场景:Entity、Bo、Vo层数据的复制,因为BeanUtils.copyProperties只能给目标对象的属性赋值,却不能在List集合下循环赋值,因此添加该方法 * 如:List<AdminEntity> 赋值到 List<AdminVo> ,List<AdminVo>中的 AdminVo 属性都会被赋予到值 * S: 数据源类 ,T: 目标类::new(eg: AdminVo::new) */ @SneakyThrows public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target, ColaBeanUtilsCallBack<S, T> callBack) { List<T> list = new ArrayList<>(sources.size()); for (S source : sources) { T t = target.get(); org.apache.commons.beanutils.BeanUtils.copyProperties(t, source); if (callBack != null) { // 回调 callBack.callBack(source, t); } list.add(t); } return list; } /** * @描述 list数据转Tree,大多使用在前台json中。 * @说明 实现接口 Tree即可 * @扩展 可通过反射获取id, pid,目前只提供Tree接口排序的实现 * @author jeff */ @SuppressWarnings({"rawtypes", "unchecked"}) public static <T extends Tree> List<T> listToTree(List<T> list) { Map<String, Tree> tempMap = new LinkedHashMap<>(); if (CollectionUtil.isEmpty(list)) { return Collections.emptyList(); } if (!(list.get(0) instanceof Tree)) { throw new BusinessException("树形转换出现异常。数据必须实现Tree接口!"); } List<T> returnList = new ArrayList<>(); for (Tree tree : (List<Tree>) list) { tempMap.put(tree.getId(), tree); } for (Tree obj : (List<Tree>) list) { String parentId = obj.getParentId(); if (tempMap.containsKey(parentId) && !obj.getId().equals(parentId)) { if (tempMap.get(parentId).getChildren() == null) { tempMap.get(parentId).setChildren(new ArrayList()); } tempMap.get(parentId).getChildren().add(obj); } else { returnList.add((T) obj); } } return returnList; } /** * 将字符串数据按照指定的类型进行转换。 * * @param typeName 实际的数据类型 * @param valStr 字符串值。 * @return Object */ public static Object getValue(String typeName, String valStr) { Object o = null; if (typeName.equals("int")) { o = Integer.parseInt(valStr); } else if (typeName.equals("short")) { o = Short.parseShort(valStr); } else if (typeName.equals("long")) { o = Long.parseLong(valStr); } else if (typeName.equals("float")) { o = Float.parseFloat(valStr); } else if (typeName.equals("double")) { o = Double.parseDouble(valStr); } else if (typeName.equals("boolean")) { o = Boolean.parseBoolean(valStr); } else if (typeName.equals("java.lang.String")) { o = valStr; } else { o = valStr; } return o; } }
二、自定义使用
List<BpmUserScriptExcle> list = BeanUtils.copyListProperties(data, BpmUserScriptExcle::new);