Apache Commons 是否有一个 toString 实用程序,它只会在结果 toString 值中包含那些不为空的字段?
例如:
public class Person {
String name;
String height;
String age;
}
并创建一个具有名称和年龄的实例。然后调用该实用程序,例如:
utility.toStringNonNull(person);
将输出:
[姓名=玛丽,年龄=28]
Apache Commons 是否有一个 toString 实用程序,它只会在结果 toString 值中包含那些不为空的字段?
例如:
public class Person {
String name;
String height;
String age;
}
并创建一个具有名称和年龄的实例。然后调用该实用程序,例如:
utility.toStringNonNull(person);
将输出:
[姓名=玛丽,年龄=28]
我可以通过扩展 Apache 的 ToStringStyle 类来做到这一点:
public static class TestStyle extends ToStringStyle{
TestStyle() {//constructor is copied from ToStringStyle.MULTI_LINE_STYLE
super();
this.setContentStart("[");
this.setFieldSeparator(SystemUtils.LINE_SEPARATOR + " ");
this.setFieldSeparatorAtStart(true);
this.setContentEnd(SystemUtils.LINE_SEPARATOR + "]");
}
//override this to do checking of null, so only non-nulls are printed out in toString
@Override
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {
if (value != null) {
super.append(buffer, fieldName, value, fullDetail);
}
}
然后使用是这样的:
public static void main(String[] args) {
Person p = new Person();
p.setName("Tester");
ToStringStyle style = new TestStyle();
System.out.println("toString = " + ToStringBuilder.reflectionToString(p, style));
}
这将导致:Person@37403a09[ name=Tester ]
你可以试试
// dump content of person
DumpUtilities.dump(person);
// dump content of person and superclass
DumpUtilities.dump(person, 1);
// dump only filled content values of person and superclass
DumpUtilities.dump(person, 1, "onlyFilled");
// dump only filled content values with name starts with abc of person and superclass
DumpUtilities.dump(person, 1, "onlyFilled", "includeName=abc.*");
// dump only filled content values without name starts with abc of person and superclass
DumpUtilities.dump(person, 1, "onlyFilled", "excludeName=abc.*");
这里是 DumpUtilities 类
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
public final class DumpUtilities {
private DumpUtilities() {
}
/**
* To dump a complete object.
*
* @param object
* @return print all fields of object.
*/
public static String dump(Object object) {
return dump(object, 1);
}
/**
* To dump a complete object.
*
* Example to print member variables of JFrame with name title
*
* JFrame frame = new JFrame(""); frame.setTitle("hello");
* logger.debug(dump(frame, 3, "onlyFilled", "newline", "indent=2"));
*
* @param object
* @param maxRecursionDeep
* @param parameterArray
* "onlyFilled" print only filled values (default false),
* "newline" new line after every value (default false), "indent"
* count of indent spaces (default 0), "excludeType" to exclude
* types e.g. "excludeType=JTextArea", "excludeName" to exclude
* names e.g. "excludeName=abc.*", "includeType" to print only
* specified types e.g. "includeType=JTextArea", "includeName" to
* print only values with specified names e.g.
* "includeName=abc.*"
* @return print all fields of object.
*/
public static String dump(Object object, int maxRecursionDeep, String... parameterArray) {
if (object == null) {
return "null";
}
Class<? extends Object> objectClass = object.getClass();
if (isInArray(objectClass, new Class<?>[] { Long.class, Integer.class, Boolean.class, Double.class, Short.class, Byte.class })
|| objectClass.isPrimitive()) {
return object.toString();
}
try {
boolean onlyFilled = booleanParameter(parameterArray, "onlyFilled");
boolean newline = booleanParameter(parameterArray, "newline");
String indent = duplicate(" ", toInt(parameter(parameterArray, "indent")));
String excludeType = parameter(parameterArray, "excludeType");
String excludeName = parameter(parameterArray, "excludeName");
String includeType = parameter(parameterArray, "includeType");
String includeName = parameter(parameterArray, "includeName");
if (objectClass == java.lang.String.class) {
String s = object.toString();
return onlyFilled && s.length() == 0 ? "" : "\"" + s + "\"";
}
StringBuffer buffer = new StringBuffer();
if (objectClass.isArray()) {
for (int i = 0; i < Array.getLength(object) && maxRecursionDeep > 0; i++) {
String value = dump(Array.get(object, i), maxRecursionDeep - 1, parameterArray);
if (onlyFilled && (value.length() == 0 || "null".equals(value))) {
continue;
}
buffer.append((i == 0 ? "" : ",") + value.replace("\n", "\n" + indent) + (newline ? "\n" : ""));
}
if ((onlyFilled && buffer.length() > 0) || !onlyFilled) {
buffer.insert(0, "[");
buffer.append("]");
}
} else {
while (objectClass != null) {
Field[] fieldArray = objectClass.getDeclaredFields();
for (int i = 0; i < fieldArray.length && maxRecursionDeep > 0; i++) {
String className;
String value;
Field field = fieldArray[i];
String name = field.getName();
if ((excludeName != null && name.matches(excludeName)) || (includeName != null && !name.matches(includeName))) {
continue;
}
try {
field.setAccessible(true);
Object fieldObject = field.get(object);
if (fieldObject != null && fieldObject.getClass().isArray()) {
String s = field.toString();
int index = s.indexOf("[");
className = s.substring(0, index >= 0 ? index : s.length());
} else {
className = field.getType().getName();
}
if ((excludeType != null && className.matches(excludeType)) || (includeType != null && !className.matches(includeType))) {
continue;
}
if (fieldObject != null && fieldObject.getClass().isArray()) {
className += "[" + Array.getLength(fieldObject) + "]";
}
value = dump(fieldObject, maxRecursionDeep - 1, parameterArray);
} catch (IllegalAccessException e) {
value = e.getMessage();
className = field.getType().getName();
}
if ((onlyFilled && value.length() > 0 && !"null".equals(value)) || !onlyFilled) {
buffer.append(indent);
if (objectClass != object.getClass()) {
buffer.append("/* " + objectClass.getSimpleName() + " */ ");
}
buffer.append((className.equals("java.lang.String") ? "String" : className) + " " + name + "=");
buffer.append(value.replace("\n", "\n" + indent) + ";" + (newline ? "\n" : ""));
}
}
objectClass = objectClass.getSuperclass();
}
if ((onlyFilled && buffer.length() > 0) || !onlyFilled) {
buffer.insert(0, "{" + ((newline && buffer.length() > 0) ? "\n" : ""));
buffer.append("}");
}
}
return buffer.toString();
} catch (Throwable t) {
return t + "\n" + stackTrace2String(t);
}
}
/**
* @param regExArray
* array of regular expressions
* @param string
* @return true if any array member matches v
*/
public static boolean matchesInArray(final String[] regExArray, final String string) {
if (regExArray == null || string == null) {
return false;
}
for (final String regEx : regExArray) {
if (string.matches(regEx)) {
return true;
}
}
return false;
}
/**
* @param array
* @param object
* @return true if array contains v
*/
public static <T> boolean contains(final T[] array, final T object) {
if (array == null || object == null) {
return false;
}
for (final T element : array) {
if (element == object || object.equals(element)) {
return true;
}
}
return false;
}
public static Method[] methodsWithAnnotation(Class c, Class annotation) {
try {
Method[] methods = c.getMethods();
List<Method> list = new ArrayList<Method>();
for (int i = 0; i < methods.length; i++) {
if (methods[i].isAnnotationPresent(annotation)) {
list.add(methods[i]);
}
}
methods = new Method[list.size()];
return list.toArray(methods);
} catch (Throwable t) {
// ignore
}
return new Method[0];
}
public static Method[] methodsWithPrefix(Class c, String prefix) {
try {
Method[] methods = c.getMethods();
List<Method> list = new ArrayList<Method>();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().startsWith(prefix)) {
list.add(methods[i]);
}
}
methods = new Method[list.size()];
return list.toArray(methods);
} catch (Throwable t) {
// ignore
}
return new Method[0];
}
public static String dumpBean(Object beanObject) {
String name = null;
try {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("{\n");
BeanInfo beanInfo = Introspector.getBeanInfo(beanObject.getClass());
for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
Method method = propertyDescriptor.getReadMethod();
Type[] parameterTypes = method.getGenericParameterTypes();
if (parameterTypes.length > 0) {
continue;
}
name = method.getName();
if ("getClass".equals(name)) {
continue;
}
Object value = method.invoke(beanObject);
if (value != null) {
name = name.startsWith("get") ? (name.substring(3, 4).toLowerCase() + name.substring(4)) : name.startsWith("is") ? (name
.substring(2, 3).toLowerCase() + name.substring(3)) : name;
stringBuffer.append(" /* " + method.getDeclaringClass().getSimpleName() + " */ " + method.getReturnType().getSimpleName() + " "
+ name + "=" + value + "\n");
}
}
stringBuffer.append("}\n");
return stringBuffer.toString();
} catch (Throwable t) {
return "error by " + name;
}
}
public static Object getField(Object object, String fieldName) throws SecurityException, NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field field = null;
for (Class<?> c = object.getClass(); c != null && field == null; c = c.getSuperclass()) {
try {
field = c.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
// ignore
}
}
if (field == null) {
throw new NoSuchFieldException();
}
boolean isAccessible = field.isAccessible();
field.setAccessible(true);
Object objectReturn = field.get(object);
field.setAccessible(isAccessible);
return objectReturn;
}
/**
* @param object
* @param memberName
* @return child of object named memberName (also private member)
*/
public static Object getMember(Object object, String memberName) {
Object objectReturn = null;
try {
Field field = object.getClass().getDeclaredField(memberName);
boolean isAccessible = field.isAccessible();
field.setAccessible(true);
objectReturn = field.get(object);
field.setAccessible(isAccessible);
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return objectReturn;
}
public static boolean isInArray(Object object, Object[] array) {
return Arrays.asList(array).indexOf(object) != -1;
}
public static boolean isInArray(Class<?> c, Class<?>[] array) {
return Arrays.asList(array).indexOf(c) != -1;
}
public static String stackTrace2String(Throwable t) {
return t + "\n" + Arrays.toString(t.getStackTrace()).replace(", ", "\n ").replace("[", "\n ").replace("]", "\n");
}
/**
* @param parameterList
* @param name
* @return hello for name b from parameterList "a=1,b=hello"
*/
public static String parameter(String parameterList, String name) {
return parameter(csv2arry(parameterList), name);
}
/**
* @param parameterList
* @param name
* @return true for name a or b from parameterList "a,b=true"
*/
public static boolean booleanParameter(String parameterList, String name) {
return booleanParameter(csv2arry(parameterList), name);
}
/**
* @param parameterArray
* @param name
* @return true for name a or b from parameterArray ["a","b=true"]
*/
public static boolean booleanParameter(String[] parameterArray, String name) {
String result = parameter(parameterArray, name);
return result != null && (result.length() == 0 || Boolean.valueOf(result));
}
/**
* @param parameterArray
* @param name
* @return null if name not found, "" for name a or "hello" for name b from
* parameterArray ["a","b=hello"]
*/
public static String parameter(String[] parameterArray, String name) {
if (parameterArray != null && name != null) {
for (String parameter : parameterArray) {
parameter = parameter.trim();
if (parameter.contains("=") && parameter.startsWith(name)) {
String rest = parameter.substring(name.length()).trim();
String argument;
if (rest.startsWith("=")) {
argument = rest.substring(1).trim();
} else {
argument = "";
}
return argument;
}
}
}
return null;
}
public static String duplicate(String string, int count) {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < count; i++) {
stringBuffer.append(string);
}
return stringBuffer.toString();
}
public static int toInt(String string) {
try {
return Integer.decode(string).intValue();
} catch (NullPointerException e) {
return 0;
} catch (NumberFormatException e) {
return 0;
}
}
/**
* @param parameterList
* @return array ["a=1","b=hello"] from parameterList "a=1,b=hello"
*/
public static String[] csv2arry(String parameterList) {
if (parameterList == null) {
return null;
}
ArrayList<String> list = new ArrayList<String>();
StringTokenizer tokenizer = new StringTokenizer(parameterList, ",");
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken().trim();
list.add(token);
}
return list.toArray(new String[list.size()]);
}
}