最近在根黑马教程的书自学java,虽然说java有些老了,我也不年轻了,但认真学一学还是能发现不少乐趣。
教程中有一个常用代码是重写POJO类的toString()方法以使打印输出实例时可以看到实例的值,而不是内存地址。对每个POJO类都重写一遍结构相同的代码简直是浪费生命,而单纯的复制粘贴然后再修改也不是好的解决方法。因为以前使用C#时对反射比较熟悉,就想着写一个工具方法来实现这个功能,到时只需要在toString()方法中调用这个方法就好了。网上搜了一下相关文章,然后就开始吧。
工具方法代码(思路见代码注释),使用用静态方法方便调用:
package com.itheima.utils;
import java.lang.reflect.Field;
import java.util.List;
import java.util.ArrayList;
public class Object2String {
public static <T> String convertToString(T object) {
if(object == null) {
return null;
}
// 获取当前对象的类型和类型名称
Class<?> clazz = object.getClass();
String className = clazz.getSimpleName();
// 如果类型名称中包含_$$_则认为是匿名代理类
// 这是考虑到mybatis在使用嵌套查询方式时返回的ResultMap使用代理包装
// TODO:是否有更好的判断方式,有待查证
if (className.contains("_$$_")) {
// 使用代理类时,获取代理类的父类,因为mybatis代理类用的时cglib代理,
// 通过动态生成子类来扩展目标类的行为
clazz = clazz.getSuperclass();
className = clazz.getSimpleName();
}
// 获取类中的所有字段,包括私有字段,使用getFields不能获取私有字段
Field[] fields = clazz.getDeclaredFields();
List<String> fvs = new ArrayList<String>(); //用于存放字段名称和值,格式为filed=value
Field.setAccessible(fields, true); //设置私有字段可访问,否则将无法读取私有字段的值
for (Field field : fields) {
String name = field.getName();
String value = "null";
try {
value = String.valueOf(field.get(object));
} catch (Exception e) {
e.printStackTrace();
}
fvs.add(name + "=" + value);
}
// 使用String.join()方法将字段名称和值拼接为字符串并用指定分隔符分隔
String info = className + "[" + String.join(", ", fvs) + "]";
return info;
}
}
创建一个POJO类用来做测试,在重写的toString方法中调用工具方法:
package com.itheima.po;
import com.itheima.utils.Object2String;
public class Customer {
private Integer id;
private String username;
private String jobs;
private String phone;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getJobs() {
return jobs;
}
public void setJobs(String jobs) {
this.jobs = jobs;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return Object2String.convertToString(this);
}
}
写一个测试类用来检验效果,这里没有测试动态代理的效果,也就是工具类中clazz.getSuperclass()部分的代码,以后有时间再补上:
package com.itheima.test;
import org.junit.Test;
import com.itheima.po.Customer;
public class UtilsTest {
// 辅助方法用于方便打印输出,虽然也可以使用静态导入out字段实现,
// 但总觉得使用import static没有简单写个方法方便
private void println(Object object) {
System.out.println(object);
}
@Test
public void convert2StringTest() {
Customer customer = new Customer();
customer.setId(1);
customer.setUsername("小六");
customer.setJobs("哎就是玩");
customer.setPhone("16894666888");
println(customer);
}
}
展示一下效果,还不错吧:
如果大家有更好的方法或思路,还请不吝赐教呀。
版权声明:本文为xCyansun原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。