反射应用之一---编写通用的toString()方法
来源:互联网 发布:win10网络不稳定 编辑:程序博客网 时间:2024/06/05 04:57
上一节总结了Java反射机制里涉及到的几个类和其用法,本节就应用这些类和方法实现一个通用的toString()方法。
要将一个对象toString,我们需要考虑到哪些方面呢?
1. 如果对象是一个数组,那么我们需要遍历其元素,然后将元素作为新的对象递归调用我们的toString方法;
2. 如果对象是个基本类型/字符串,那么可以直接返回其value;
3. 如果对象是个复杂对象,那么我们需要获取其所有的字段,然后遍历,如果该字段是基本类型/字符串,则直接返回其value,否则将每个字段作为新的对象递归调用我们的toString方法;
4. 不处理Map对象,因为其实现类都实现了toString方法。
实现如下:
package reflect;import java.lang.reflect.AccessibleObject;import java.lang.reflect.Array;import java.lang.reflect.Field;import java.lang.reflect.Modifier;import java.util.ArrayList;import java.util.List;/** * @author rambo.pan * 2016年10月10日 */public class ObjectAnalyzer { private static final String NULL_STRING = "null"; private static final String VISITED_STRING = "..."; //该数组用来记录已解析过的对象类型 private List<Object> visited = new ArrayList<Object>(); /** * 递归方法,object是个数组,则遍历其元素,递归调用该方法;否则是个类实例,则遍历其所有字段 * @param obj * @return */ public String toString(Object obj){ //如果对象为空,则返回null if (obj == null) { return NULL_STRING; } //如果对象已被处理过,则返回,针对于 A、B对象相互组合的情况,否则会循环递归,导致StackOverFlow if (visited.contains(obj)) { return VISITED_STRING; } visited.add(obj); //获取对象的Class实例,同一个类的对象,共有一个相应的Class实例,在类被加载到虚拟机时就存储在方法区中了 Class<?> cl = obj.getClass(); //如果对象正好是String对象,则强转后直接返回 if (cl == String.class) { return (String)obj; } //如果object是个数组,则遍历其元素,对元素进行toString(Object)递归调用 if (cl.isArray()) { //获取数组的元素类型 String r = cl.getComponentType() + "[]{"; for (int i = 0; i < Array.getLength(obj); i++) { if (i > 0) { r += ","; } //获取指定下标的数组元素 Object val = Array.get(obj, i); //如果元素是原始/基本类型(Java共8种基本类型),则直接输出 if (cl.getComponentType().isPrimitive()) { r += val; }else {//否则递归调用,直到其为原始类型 r += toString(val); } } //对数组元素遍历完成,返回。 return r + "}"; } //object不是数组类型,首先获取其类型Name String r = cl.getName(); //遍历object的所有字段,然后获取字段的Name和Value,之后再遍历其父类,直到遍历到父类为Object do{ r += "["; //获取object的所有字段,无论访问限制符是public还是private,但不包括其从父类继承来的字段 Field[] fields = cl.getDeclaredFields(); //设置字段的访问权限为可访问 AccessibleObject.setAccessible(fields, true); for (Field field : fields) { //忽略static属性 if (Modifier.isStatic(field.getModifiers())) { continue; } if (!r.endsWith("[")) { r += ","; } r += field.getName() + "="; try{ //获取字段类型和字段的值 Class<?> t = field.getType(); Object val = field.get(obj); //如果字段类型是原始类型,则直接输出;否则递归调用toString(Object) if (t.isPrimitive()) { r += val; }else { r += toString(val); } }catch (Exception e) { e.printStackTrace(); } } //一个类型的字段遍历结束 r += "]"; //获取该类型的父类Class实例,然后继续该循环 cl = cl.getSuperclass(); }while(cl != null); //类型遍历完成,返回object的字符串结果 return r; }}
0 0
- 反射应用之一---编写通用的toString()方法
- 利用java反射机制编写通用的toString 方法
- 使用java反射编写通用的toString()方法
- 一种通用的toString()方法的编写
- java反射实现的通用toString
- 一个通用的类的toString()方法
- 一个通用的类的toString()方法
- 程序清单-通用的toString方法
- 三十一、反射的应用之一
- JDBC:利用反射及JDBC元数据编写通用的查询方法
- JDBC:利用 ResultSetMetaData 和反射编写通用查询方法
- 关于@Override toString()方法的应用
- java反射覆盖toString()方法
- 利用反射重写toString()方法
- 利用反射重写tostring方法
- 利用反射模拟Tomcat类加载器的toString方法
- 一个通用快速的反射方法调用
- 利用反射泛型编写通用的Dao
- Mysql中类似于nvl()函数的ifnull()函数
- AndroirStudio关于gradle的配置
- android自定义对话框(AlertDialog)
- Android Alert Dialog点击按钮对话框不关闭
- linux下各目录的作用
- 反射应用之一---编写通用的toString()方法
- poj3278 bfs
- 解决Spring注解错误:ComponentScanBeanDefinitionParser are only available on JDK 1.5 and higher
- windows客户端开发--windows api大全
- 使用wxPython实现的简易版记事本
- this指针的用法
- OpenGL ES
- Linux上SVN的 "db/txn-current-lock: Permission denied" 问题解决办法
- Android之内存管理及优化-干货