All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sviolet.thistle.util.reflect.ClassPrinter Maven / Gradle / Ivy

/*
 * Copyright (C) 2015-2017 S.Violet
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Project GitHub: https://github.com/shepherdviolet/thistle
 * Email: [email protected]
 */

package sviolet.thistle.util.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Comparator;

import sviolet.thistle.util.judge.CheckUtils;

/**
 * 

将一个类或一个对象的数据/构造函数/方法打印出来

* * @author S.Violet */ public class ClassPrinter { public static final String CLASS_IS_NULL = "Class: null"; public static final String OBJECT_IS_NULL = "Object: null"; private static final int POSITION_CLASS = 0; private static final int POSITION_FIELD = 1; private static final int POSITION_CONSTRUCTOR = 2; private static final int POSITION_METHOD = 3; private static final Params DEFAULT_PARAMS = new Params(); /** * 打印class * * @param clazz class * @param traversals true:遍历父类 */ public static String print(Class clazz, boolean traversals) throws IllegalAccessException { return print(clazz, new Params().setTraversals(traversals)); } /** * 打印class * * @param clazz class * @param params 打印参数 */ public static String print(Class clazz, Params params) throws IllegalAccessException { if (params == null) { params = DEFAULT_PARAMS; } if (clazz == null) { return params.buildClassTitle() + '\n' + CLASS_IS_NULL; } Class current = clazz; StringBuilder stringBuilder = new StringBuilder(); print(current, null, stringBuilder, params); while (params.isTraversals() && (current = current.getSuperclass()) != null && !Object.class.equals(current)) { print(current, null, stringBuilder, params); } return stringBuilder.toString(); } /** * 打印对象 * * @param obj 对象 * @param traversals true:遍历父类 */ public static String print(Object obj, boolean traversals) throws IllegalAccessException { return print(obj, new Params().setTraversals(traversals)); } /** * 打印对象 * * @param obj 对象 * @param params 打印参数 */ public static String print(Object obj, Params params) throws IllegalAccessException { if (params == null) { params = DEFAULT_PARAMS; } if (obj == null) { return params.buildClassTitle() + '\n' + OBJECT_IS_NULL; } Class current = obj.getClass(); StringBuilder stringBuilder = new StringBuilder(); print(current, obj, stringBuilder, params); while (params.isTraversals() && (current = current.getSuperclass()) != null && !Object.class.equals(current)) { print(current, obj, stringBuilder, params); } return stringBuilder.toString(); } private static void print(Class clazz, Object obj, StringBuilder stringBuilder, Params params) throws IllegalAccessException { printClassInfo(clazz, stringBuilder, params); if (params.isPrintFields()) { printClassFields(clazz, obj, stringBuilder, params); } if (params.isPrintConstructors()) { printClassConstructors(clazz, stringBuilder, params); } if (params.isPrintMethods()) { printClassMethods(clazz, stringBuilder, params); } stringBuilder.append("}\n"); } private static void printClassMethods(Class clazz, StringBuilder stringBuilder, Params params) { stringBuilder.append(" ").append(params.buildMethodTitle()).append('\n'); Method[] methods = ReflectCache.getDeclaredMethods(clazz); if (params.isSorted()) { Arrays.sort(methods, METHOD_COMPARATOR); } for (Method method : methods) { String name = method.getName(); if (!params.isIncludeSpecial() && name.contains("$")) { continue; } stringBuilder.append(" "); printModifiers(method.getModifiers(), stringBuilder, POSITION_METHOD); stringBuilder.append(method.getReturnType().getName()) .append(" ") .append(name) .append("("); Class[] paramTypes = method.getParameterTypes(); for (int i = 0; i < paramTypes.length; i++) { if (i != 0) { stringBuilder.append(", "); } stringBuilder.append(paramTypes[i].getName()); } stringBuilder.append(")"); Class[] exceptions = method.getExceptionTypes(); if (exceptions.length > 0) { stringBuilder.append(" throws "); for (int i = 0 ; i < exceptions.length ; i++) { stringBuilder.append(exceptions[i].getName()); if (i < exceptions.length - 1) { stringBuilder.append(", "); } } } stringBuilder.append(" {...}\n"); } } private static void printClassConstructors(Class clazz, StringBuilder stringBuilder, Params params) { stringBuilder.append(" ").append(params.buildConstructorTitle()).append('\n'); Constructor[] constructors = ReflectCache.getDeclaredConstructors(clazz); if (params.isSorted()) { Arrays.sort(constructors, CONSTRUCTOR_COMPARATOR); } for (Constructor constructor : constructors) { stringBuilder.append(" "); printModifiers(constructor.getModifiers(), stringBuilder, POSITION_CONSTRUCTOR); stringBuilder.append(clazz.getSimpleName()) .append("("); Class[] paramTypes = constructor.getParameterTypes(); for (int j = 0; j < paramTypes.length; j++) { if (j != 0) { stringBuilder.append(", "); } stringBuilder.append(paramTypes[j].getName()); } stringBuilder.append(")"); Class[] exceptions = constructor.getExceptionTypes(); if (exceptions.length > 0) { stringBuilder.append(" throws "); for (int i = 0 ; i < exceptions.length ; i++) { stringBuilder.append(exceptions[i].getName()); if (i < exceptions.length - 1) { stringBuilder.append(", "); } } } stringBuilder.append(" {...}\n"); } } private static void printClassFields(Class clazz, Object obj, StringBuilder stringBuilder, Params params) throws IllegalAccessException { stringBuilder.append(" ").append(params.buildFieldTitle()).append('\n'); Field[] fields = ReflectCache.getDeclaredFields(clazz); if (params.isSorted()) { Arrays.sort(fields, FIELD_COMPARATOR); } for (Field field : fields) { int modifiers = field.getModifiers(); String name = field.getName(); if (!params.isIncludeSpecial() && name.contains("$")) { continue; } field.setAccessible(true); stringBuilder.append(" "); printModifiers(modifiers, stringBuilder, POSITION_FIELD); stringBuilder.append(field.getType().getName()) .append(" ") .append(name); if (obj != null || CheckUtils.isFlagMatch(modifiers, Modifier.STATIC)) { stringBuilder.append(" = ") .append(field.get(obj)); } else { stringBuilder.append(';'); } stringBuilder.append('\n'); } } private static void printClassInfo(Class clazz, StringBuilder stringBuilder, Params params) { if (stringBuilder.length() <= 0) { stringBuilder.append(params.buildClassTitle()).append('\n'); } else { stringBuilder.append(params.buildSuperClassTitle()).append('\n'); } printModifiers(clazz.getModifiers(), stringBuilder, POSITION_CLASS); stringBuilder.append("class ").append(clazz.getName()); Class superClass = clazz.getSuperclass(); if (superClass != null) { stringBuilder.append("\n extends ").append(superClass.getName()); } Class[] interfaces = clazz.getInterfaces(); if (interfaces.length > 0) { if (params.isSorted()) { Arrays.sort(interfaces, CLASS_COMPARATOR); } stringBuilder.append("\n implements "); for (int i = 0 ; i < interfaces.length ; i++) { stringBuilder.append(interfaces[i].getName()); if (i < interfaces.length - 1) { stringBuilder.append(", "); } } } stringBuilder.append(" {\n"); } private static void printModifiers(int modifiers, StringBuilder stringBuilder, int position) { if (CheckUtils.isFlagMatch(modifiers, Modifier.PUBLIC)) { stringBuilder.append("public "); } if (CheckUtils.isFlagMatch(modifiers, Modifier.PRIVATE)) { stringBuilder.append("private "); } if (CheckUtils.isFlagMatch(modifiers, Modifier.PROTECTED)) { stringBuilder.append("protected "); } if (CheckUtils.isFlagMatch(modifiers, Modifier.STATIC)) { stringBuilder.append("static "); } if (CheckUtils.isFlagMatch(modifiers, Modifier.FINAL)) { stringBuilder.append("final "); } if (CheckUtils.isFlagMatch(modifiers, Modifier.SYNCHRONIZED)) { stringBuilder.append("synchronized "); } if (CheckUtils.isFlagMatch(modifiers, Modifier.VOLATILE) && position == POSITION_FIELD) { stringBuilder.append("volatile "); } if (CheckUtils.isFlagMatch(modifiers, Modifier.NATIVE)) { stringBuilder.append("native "); } if (CheckUtils.isFlagMatch(modifiers, Modifier.INTERFACE)) { stringBuilder.append("interface "); } if (CheckUtils.isFlagMatch(modifiers, Modifier.ABSTRACT)) { stringBuilder.append("abstract "); } if (CheckUtils.isFlagMatch(modifiers, Modifier.STRICT)) { stringBuilder.append("strict "); } } private static final Comparator> CLASS_COMPARATOR = new Comparator>() { @Override public int compare(Class o1, Class o2) { return o1.getName().compareTo(o2.getName()); } }; private static final Comparator FIELD_COMPARATOR = new Comparator() { @Override public int compare(Field o1, Field o2) { return o1.getName().compareTo(o2.getName()); } }; private static final Comparator> CONSTRUCTOR_COMPARATOR = new Comparator>() { @Override public int compare(Constructor o1, Constructor o2) { int result = o1.getName().compareTo(o2.getName()); if (result != 0) { return result; } return o1.toString().compareTo(o2.toString()); } }; private static final Comparator METHOD_COMPARATOR = new Comparator() { @Override public int compare(Method o1, Method o2) { int result = o1.getName().compareTo(o2.getName()); if (result != 0) { return result; } return o1.toString().compareTo(o2.toString()); } }; public static class Params { private boolean traversals = true; private boolean printFields = true; private boolean printFieldValues = true; private boolean printConstructors = true; private boolean printMethods = true; private boolean includeSpecial = false; private boolean sorted = false; private String classTitle = "#### Class #########################################################################################"; private String superClassTitle = "++++ Super Class +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"; private String fieldTitle = "// Fields"; private String constructorTitle = "// Constructors"; private String methodTitle = "// Methods"; public boolean isTraversals() { return traversals; } /** * 遍历父类, 默认true */ public Params setTraversals(boolean traversals) { this.traversals = traversals; return this; } public boolean isPrintFields() { return printFields; } /** * 打印Field, 默认true */ public Params setPrintFields(boolean printFields) { this.printFields = printFields; return this; } public boolean isPrintFieldValues() { return printFieldValues; } /** * 打印Field值 (打印对象时有效), 默认true */ public Params setPrintFieldValues(boolean printFieldValues) { this.printFieldValues = printFieldValues; return this; } public boolean isPrintConstructors() { return printConstructors; } /** * 打印构造器, 默认true */ public Params setPrintConstructors(boolean printConstructors) { this.printConstructors = printConstructors; return this; } public boolean isPrintMethods() { return printMethods; } /** * 打印方法, 默认true */ public Params setPrintMethods(boolean printMethods) { this.printMethods = printMethods; return this; } public boolean isIncludeSpecial() { return includeSpecial; } /** * 包含特殊的Method和Field */ public Params setIncludeSpecial(boolean includeSpecial) { this.includeSpecial = includeSpecial; return this; } public boolean isSorted() { return sorted; } /** * 内容排序, 使同一个类/对象打印出来的结果保持一致(否则每次顺序可能不同), 默认false */ public Params setSorted(boolean sorted) { this.sorted = sorted; return this; } public String getClassTitle() { return classTitle; } private String buildClassTitle() { return CheckUtils.isEmpty(classTitle) ? "" : classTitle; } /** * 类标题, 可为空 */ public Params setClassTitle(String classTitle) { this.classTitle = classTitle; return this; } public String getSuperClassTitle() { return superClassTitle; } private String buildSuperClassTitle() { return CheckUtils.isEmpty(superClassTitle) ? "" : superClassTitle; } /** * 父类标题, 可为空 */ public Params setSuperClassTitle(String superClassTitle) { this.superClassTitle = superClassTitle; return this; } public String getFieldTitle() { return fieldTitle; } private String buildFieldTitle() { return CheckUtils.isEmpty(fieldTitle) ? "" : fieldTitle; } /** * Field标题, 可为空 */ public Params setFieldTitle(String fieldTitle) { this.fieldTitle = fieldTitle; return this; } public String getConstructorTitle() { return constructorTitle; } private String buildConstructorTitle() { return CheckUtils.isEmpty(constructorTitle) ? "" : constructorTitle; } /** * 构造器标题, 可为空 */ public Params setConstructorTitle(String constructorTitle) { this.constructorTitle = constructorTitle; return this; } public String getMethodTitle() { return methodTitle; } private String buildMethodTitle() { return CheckUtils.isEmpty(methodTitle) ? "" : methodTitle; } /** * 方法标题, 可为空 */ public Params setMethodTitle(String methodTitle) { this.methodTitle = methodTitle; return this; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy