Skip to content

Instantly share code, notes, and snippets.

@zhanggang807
Last active March 9, 2023 06:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zhanggang807/b41270dcd42feef4136237e632c1e3e3 to your computer and use it in GitHub Desktop.
Save zhanggang807/b41270dcd42feef4136237e632c1e3e3 to your computer and use it in GitHub Desktop.
Print Pojo Fields Recursive
import sun.reflect.generics.reflectiveObjects.TypeVariableImpl;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* 递归打印pojo的属性类型信息,getter setter方法
* tab用于表示层级关系,可以方便的复制到思维导图类软件
* 后面可以写成 idea 插件 只依赖jdk
*
* 是不是比较适合用 visitor 模式? 使用asm类似的框架比较合适??
* 有时候自己重复造轮子也挺好的,不过时间精力有限
*
* Creted by zhanggang807 on 2018/4/19.
*/
public class PrintPojoFieldsRecursive {
/** 操作意图 PrintPojoFieldsRecursive.Intent */
private int intent;
/** 是否递归处理 */
private boolean recursiveFlag;
/** struct 输出 */
private StringBuilder structStrBuilder;
/** getter 输出 */
private StringBuilder getterStrBuilder;
/** setter 输出 */
private StringBuilder setterStrBuilder;
/** 意图集合 */
private static final List<String> intentList = Arrays.asList(new String[]{"struct", "getter", "setter"});
/** 基本数据类型 */
private static final List<String> baseTypeList = Arrays.asList(("boolean,byte,short,int,long,char,fload," +
"double,Boolean,Byte,Short,Integer,Long,Character,Float,Double,String,Date,Object").split(","));
/** 泛型类型 */
private static final List<String> genericTypeList = Arrays.asList("List,Map,Set".split(","));
/** 自定义字段过滤 */
//private static final List<String> filterList = Arrays.asList("serialVersionUID".split(","));
private static final List<String> filterList = Arrays.asList("serialVersionUID".split(","));
/** 需要过滤的父类 */
private static final List<String> filterSuperClassList = Arrays.asList("Object,Enum".split(","));
public static void main(String[] args) {
PrintPojoFieldsRecursive printPojoFieldsRecursive = new PrintPojoFieldsRecursive(Intent.struct | Intent.getter | Intent.setter, true);//打印目的 是否递归
printPojoFieldsRecursive.printPojoFieldsRecursive(AA.class);//开始处理
try {
Thread.sleep(1000);//防止idea的debug tool window log confuse me.
} catch (InterruptedException e) {
e.printStackTrace();
}
//所有的父类都是java.lang.Object, Object类上面只有方法没有字段
//所有枚举类的父类都是java.lang.Enum, Enum类上面有两个字段 name ordinal
//所以要过过滤掉 Object Enum两个父类
}
/** 构造器 */
public PrintPojoFieldsRecursive(int intent, boolean recursiveFlag) {
this.intent = intent;
this.recursiveFlag = recursiveFlag;
if (Intent.contains(intent, Intent.struct)){
structStrBuilder = new StringBuilder();
}
if (Intent.contains(intent, Intent.getter)) {
getterStrBuilder = new StringBuilder();
}
if (Intent.contains(intent, Intent.setter)) {
setterStrBuilder = new StringBuilder();
}
}
/** 对外的API方法,封装 */
public void printPojoFieldsRecursive(Class<?> clazz){
printPojoFieldsRecursive(clazz, 0);
if (Intent.contains(intent, Intent.struct)){
System.out.print(structStrBuilder.toString());
System.out.println("================== " + intentList.get(0) + " 处理完成 ======================");
}
if (Intent.contains(intent, Intent.getter)) {
System.out.print(getterStrBuilder.toString());
System.out.println("================== " + intentList.get(1) + " 处理完成 ======================");
}
if (Intent.contains(intent, Intent.setter)) {
System.out.print(setterStrBuilder.toString());
System.out.println("================== " + intentList.get(2) + " 处理完成 ======================");
}
}
/** 递归打印字段信息 */
private void printPojoFieldsRecursive(Class<?> clazz, int level) {
if (level > 0 && ! recursiveFlag){//是否递归
return ;
}
Class<?> superclass = clazz.getSuperclass();//处理父类
if (superclass != null && ! filterSuperClassList.contains(superclass.getSimpleName())){
printPojoFieldsRecursive(superclass, 0);
}
Field[] fields = clazz.getDeclaredFields();
//Field[] fields = clazz.getFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
String fieldName = field.getName();
if (filterList.contains(fieldName)){//自定义字段过滤
continue;
}
if (level > 0){//过滤当前类型的泛型成员属性,
if (field.getGenericType() instanceof TypeVariableImpl){
TypeVariableImpl a = (TypeVariableImpl) field.getGenericType();
if (a != null){
String name = a.getName();
if (name.equals("T") ){
continue ;
}
}
}
}
//if (! Modifier.isPrivate(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) {//过滤非private字段 过滤静态类型字段
// //System.out.println("过滤" + fieldName);
// continue;
//}
if (Modifier.isStatic(field.getModifiers())) {//过滤非private字段 过滤静态类型字段
//System.out.println("过滤" + fieldName);
continue;
}
Class<?> type = field.getType();
String simpleTypeName = type.getSimpleName();
if (type.isEnum()){//单独处理枚举字段
printStrWithTabPre(level, simpleTypeName + "-[enum]", fieldName);
continue;
}
if (type.isArray()) {//是数组类型
printStrWithTabPre(level, simpleTypeName, fieldName);
if ((! baseTypeList.contains(type.getComponentType().getSimpleName()))) {
printPojoFieldsRecursive(type.getComponentType(), level + 1);
}
} else if (! baseTypeList.contains(simpleTypeName)) {//非基本数据类型
if (field.getGenericType() instanceof ParameterizedType) {//存在泛型
printStrWithTabPre(level, simpleTypeName + "<>", fieldName);
if (! genericTypeList.contains(simpleTypeName)){
printPojoFieldsRecursive(type, level + 1);
}
ParameterizedType pt = (ParameterizedType) field.getGenericType();
//得到泛型里的class类型对象
Type[] actualTypeArguments = pt.getActualTypeArguments();
for (int j = 0; j < actualTypeArguments.length; j++) {
Class<?> genericClazz = (Class<?>) actualTypeArguments[j];
if (! baseTypeList.contains(genericClazz.getSimpleName())){
if (i == 0){//第一个打印,第二个就不打印了,用于聚合map这类k,v的处理
printStrWithTabPre(level, simpleTypeName, fieldName);
}
printStrWithTabPre(level + 1, genericClazz.getSimpleName(), "");
printPojoFieldsRecursive(genericClazz, level + 2);
} else {
printStrWithTabPre(level + 1, genericClazz.getSimpleName(), "");
}
}
} else {//不是泛型,就按自定义类型处理吧
printStrWithTabPre(level, simpleTypeName, fieldName);
printPojoFieldsRecursive(type, level + 1);
}
} else {//普通数据类型吧
printStrWithTabPre(level, simpleTypeName, fieldName);
}
}
}
/** 打印以指定数量tab开头的字符串 */
private void printStrWithTabPre(int level, String typeName, String fieldName) {
if (Intent.contains(intent, Intent.struct)){
structStrBuilder.append(getTabString(level) + typeName + " " + fieldName).append("\n");
}
if (Intent.contains(intent, Intent.getter) && fieldName != null && fieldName.length() > 0){
getterStrBuilder.append(getTabString(level) + "obj.get" + upperCaseFirstChar(fieldName) + "();").append("\n");
}
if (Intent.contains(intent, Intent.setter) && fieldName != null && fieldName.length() > 0){
setterStrBuilder.append(getTabString(level) + "obj.set" + upperCaseFirstChar(fieldName) + "();").append("\n");
}
}
private String upperCaseFirstChar(String str){
if (str == null || str.length() <= 0){
return "";
}
char[] cs = str.toCharArray();
cs[0] -= 32;
return String.valueOf(cs);
}
/** 获得指定数量的tab字符串 */
private String getTabString(int level) {
if (level <= 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < level; i++) {
sb.append("\t");
}
return sb.toString();
}
public int getIntent() {
return intent;
}
public void setIntent(int intent) {
this.intent = intent;
}
public boolean isRecursiveFlag() {
return recursiveFlag;
}
public void setRecursiveFlag(boolean recursiveFlag) {
this.recursiveFlag = recursiveFlag;
}
}
/** 意图 */
class Intent{
/** 结构 */
public static final int struct = 0x01 << 0;
/** getter */
public static final int getter = 0x01 << 1;
/** setter */
public static final int setter = 0x01 << 2;
public static boolean contains(int opMark , int mask) {
return (opMark & mask ) != 0 ;
}
}
/** 用于测试的类 */
class AA extends User{
private static final long serialVersionUID = 4347301630877842143L;
private static String string;
public static String string2342;
private boolean flag_0;
private Boolean flag_1;
private List list_0;
private List<String> list_1;
private Map map_0;
private Map<String, String> map_1;
private Map<String, User> map_2;
private String[] strArr;
private User[] userArr;
private List<User> userList;
private Set userSet_0;
private Set<User> userSet_1;
}
/** 用于测试的类 */
class User{
private int age;
private int num;
private String name;
private String address;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
@zhanggang807
Copy link
Author

when have time need to develop an IDEA plugin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment