从类中打印所有variables值

我有一个有关Person的信息的类,看起来像这样:

public class Contact { private String name; private String location; private String address; private String email; private String phone; private String fax; public String toString() { // Something here } // Getters and setters. } 

我想toString()返回this.name +" - "+ this.locations + ...为所有variables。 我试图用这个问题所示的reflection来实现它,但我无法打印实例variables。

什么是解决这个问题的正确方法?

从实现到string :

 public String toString() { StringBuilder result = new StringBuilder(); String newLine = System.getProperty("line.separator"); result.append( this.getClass().getName() ); result.append( " Object {" ); result.append(newLine); //determine fields declared in this class only (no fields of superclass) Field[] fields = this.getClass().getDeclaredFields(); //print field names paired with their values for ( Field field : fields ) { result.append(" "); try { result.append( field.getName() ); result.append(": "); //requires access to private field: result.append( field.get(this) ); } catch ( IllegalAccessException ex ) { System.out.println(ex); } result.append(newLine); } result.append("}"); return result.toString(); } 

为什么你想重新发明轮子,有开源,已经很好地做这项工作。

apache common-langs和spring都支持一些非常灵活的构build模式

对于阿帕奇,这是你如何反思

 @Override public String toString() { return ToStringBuilder.reflectionToString(this); } 

如果您只想打印您关心的字段,您可以这样做。

 @Override public String toString() { return new ToStringBuilder(this) .append("name", name) .append("location", location) .append("address", address) .toString(); } 

您可以尽可能使用非默认的ToStringStyle “打样”打印输出,甚至可以使用自己的样式进行自定义。

我没有亲自尝试Spring ToStringCreator API,但它看起来非常相似。

如果你使用Eclipse,这应该很容易:

1.按Alt + Shift + S

2.select“生成toString()…”

请享用! 你可以有任何toString()的模板。

这也适用于getter / setter。

genericstoString()单行,使用reflection和样式自定义:

 import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; ... public String toString() { return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE); } 

当访问字段值时,传递实例而不是null。

为什么不在这里使用代码生成? 例如,Eclipse会为你生成一个可重用的toString实现。

另一个简单的方法是让Lombok为你生成toString方法。

为了这:

  1. 只需将Lombok添加到您的项目中
  2. 将注释@ToString添加到您的类的定义
  3. 编译你的类/项目,并完成

所以例如在你的情况下,你的类看起来像这样:

 @ToString public class Contact { private String name; private String location; private String address; private String email; private String phone; private String fax; // Getters and setters. } 

这种情况下的输出示例:

 Contact(name=John, location=USA, address=SF, email=foo@bar.com, phone=99999, fax=88888) 

更多关于如何使用注解@ToString

注意:你也可以让Lombok为你生成getters和setters , 这里是完整的function列表。

加上@cletus答案,您必须获取所有模型字段(上层),并设置field.setAccessible(true)来访问私有成员。 这是完整的片段:

 @Override public String toString() { StringBuilder result = new StringBuilder(); String newLine = System.getProperty("line.separator"); result.append(getClass().getSimpleName()); result.append( " {" ); result.append(newLine); List<Field> fields = getAllModelFields(getClass()); for (Field field : fields) { result.append(" "); try { result.append(field.getName()); result.append(": "); field.setAccessible(true); result.append(field.get(this)); } catch ( IllegalAccessException ex ) { // System.err.println(ex); } result.append(newLine); } result.append("}"); result.append(newLine); return result.toString(); } private List<Field> getAllModelFields(Class aClass) { List<Field> fields = new ArrayList<>(); do { Collections.addAll(fields, aClass.getDeclaredFields()); aClass = aClass.getSuperclass(); } while (aClass != null); return fields; } 

如果来自ReflectionToStringBuilder.toString()的输出对于您来说是不够可读的,则代码如下:
1)按字母顺序排列字段名称
2)在行的开头标记带星号的非空字段

 public static Collection<Field> getAllFields(Class<?> type) { TreeSet<Field> fields = new TreeSet<Field>( new Comparator<Field>() { @Override public int compare(Field o1, Field o2) { int res = o1.getName().compareTo(o2.getName()); if (0 != res) { return res; } res = o1.getDeclaringClass().getSimpleName().compareTo(o2.getDeclaringClass().getSimpleName()); if (0 != res) { return res; } res = o1.getDeclaringClass().getName().compareTo(o2.getDeclaringClass().getName()); return res; } }); for (Class<?> c = type; c != null; c = c.getSuperclass()) { fields.addAll(Arrays.asList(c.getDeclaredFields())); } return fields; } public static void printAllFields(Object obj) { for (Field field : getAllFields(obj.getClass())) { field.setAccessible(true); String name = field.getName(); Object value = null; try { value = field.get(obj); } catch (IllegalArgumentException | IllegalAccessException e) { e.printStackTrace(); } System.out.printf("%s %s.%s = %s;\n", value==null?" ":"*", field.getDeclaringClass().getSimpleName(), name, value); } } 

testing装置:

 public static void main(String[] args) { A a = new A(); ax = 1; B b = new B(); bx=10; by=20; System.out.println("======="); printAllFields(a); System.out.println("======="); printAllFields(b); System.out.println("======="); } class A { int x; String z = "z"; Integer b; } class B extends A { int y; private double z = 12345.6; public int a = 55; } 

我会得到我的答案如下:

 import java.io.IOException; import java.io.Writer; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; public class findclass { public static void main(String[] args) throws Exception, IllegalAccessException { new findclass().findclass(new Object(), "objectName"); new findclass().findclass(1213, "int"); new findclass().findclass("ssdfs", "String"); } public Map<String, String>map=new HashMap<String, String>(); public void findclass(Object c,String name) throws IllegalArgumentException, IllegalAccessException { if(map.containsKey(c.getClass().getName() + "@" + Integer.toHexString(c.hashCode()))){ System.out.println(c.getClass().getSimpleName()+" "+name+" = "+map.get(c.getClass().getName() + "@" + Integer.toHexString(c.hashCode()))+" = "+c); return;} map.put(c.getClass().getName() + "@" + Integer.toHexString(c.hashCode()), name); Class te=c.getClass(); if(te.equals(Integer.class)||te.equals(Double.class)||te.equals(Float.class)||te.equals(Boolean.class)||te.equals(Byte.class)||te.equals(Long.class)||te.equals(String.class)||te.equals(Character.class)){ System.out.println(c.getClass().getSimpleName()+" "+name+" = "+c); return; } if(te.isArray()){ if(te==int[].class||te==char[].class||te==double[].class||te==float[].class||te==byte[].class||te==long[].class||te==boolean[].class){ boolean dotflag=true; for (int i = 0; i < Array.getLength(c); i++) { System.out.println(Array.get(c, i).getClass().getSimpleName()+" "+name+"["+i+"] = "+Array.get(c, i)); } return; } Object[]arr=(Object[])c; for (Object object : arr) { if(object==null) System.out.println(c.getClass().getSimpleName()+" "+name+" = null"); else { findclass(object, name+"."+object.getClass().getSimpleName()); } } } Field[] fields=c.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); if(field.get(c)==null){ System.out.println(field.getType().getSimpleName()+" "+name+"."+field.getName()+" = null"); continue; } findclass(field.get(c),name+"."+field.getName()); } if(te.getSuperclass()==Number.class||te.getSuperclass()==Object.class||te.getSuperclass()==null) return; Field[]faFields=c.getClass().getSuperclass().getDeclaredFields(); for (Field field : faFields) { field.setAccessible(true); if(field.get(c)==null){ System.out.println(field.getType().getSimpleName()+" "+name+"<"+c.getClass().getSuperclass().getSimpleName()+"."+field.getName()+" = null"); continue; } Object check=field.get(c); findclass(field.get(c),name+"<"+c.getClass().getSuperclass().getSimpleName()+"."+field.getName()); } } public void findclass(Object c,String name,Writer writer) throws IllegalArgumentException, IllegalAccessException, IOException { if(map.containsKey(c.getClass().getName() + "@" + Integer.toHexString(c.hashCode()))){ writer.append(c.getClass().getSimpleName()+" "+name+" = "+map.get(c.getClass().getName() + "@" + Integer.toHexString(c.hashCode()))+" = "+c+"\n"); return;} map.put(c.getClass().getName() + "@" + Integer.toHexString(c.hashCode()), name); Class te=c.getClass(); if(te.equals(Integer.class)||te.equals(Double.class)||te.equals(Float.class)||te.equals(Boolean.class)||te.equals(Byte.class)||te.equals(Long.class)||te.equals(String.class)||te.equals(Character.class)){ writer.append(c.getClass().getSimpleName()+" "+name+" = "+c+"\n"); return; } if(te.isArray()){ if(te==int[].class||te==char[].class||te==double[].class||te==float[].class||te==byte[].class||te==long[].class||te==boolean[].class){ boolean dotflag=true; for (int i = 0; i < Array.getLength(c); i++) { writer.append(Array.get(c, i).getClass().getSimpleName()+" "+name+"["+i+"] = "+Array.get(c, i)+"\n"); } return; } Object[]arr=(Object[])c; for (Object object : arr) { if(object==null){ writer.append(c.getClass().getSimpleName()+" "+name+" = null"+"\n"); }else { findclass(object, name+"."+object.getClass().getSimpleName(),writer); } } } Field[] fields=c.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); if(field.get(c)==null){ writer.append(field.getType().getSimpleName()+" "+name+"."+field.getName()+" = null"+"\n"); continue; } findclass(field.get(c),name+"."+field.getName(),writer); } if(te.getSuperclass()==Number.class||te.getSuperclass()==Object.class||te.getSuperclass()==null) return; Field[]faFields=c.getClass().getSuperclass().getDeclaredFields(); for (Field field : faFields) { field.setAccessible(true); if(field.get(c)==null){ writer.append(field.getType().getSimpleName()+" "+name+"<"+c.getClass().getSuperclass().getSimpleName()+"."+field.getName()+" = null"+"\n"); continue; } Object check=field.get(c); findclass(field.get(c),name+"<"+c.getClass().getSuperclass().getSimpleName()+"."+field.getName(),writer); } } }