打印类中的所有变量值


72

我有一堂课,其中包含有关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 + ...所有变量。我试图使用反射来实现它,如该问题所示,但是我无法打印实例变量。

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


当您尝试反射时会发生什么?它对我
有用

我不知道该如何传递给field.get()。阅读了cletus的答案后,我知道应该通过“ this”。
Macarse

Answers:


101

实现toString

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();
}

15

5
@SivakumarK链接被打破用途:commons.apache.org/proper/commons-lang/apidocs/org/apache/...代替
库奇

@kuchi他们已将其更新为3.1,更改了我提供的URL使其可以正常工作
Sivakumar Kailasam,2013年

需要处理数组字段,我很快就会在inshallah做。
Amr Lotfy

51

当有开源已经很好地完成这项工作时,为什么要重新发明轮子呢?

apache公共语言spring都支持一些非常灵活的构建器模式

对于apache,这是您的反思方式

@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,但是看起来非常相似。


春天一one脚,只是样式而已,没有反射
Kalpesh Soni

35

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

1.按Alt+ Shift+S

2.选择“ Generate toString()...”

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

这也适用于getter / setter。


11

通用toString()一排,使用反射和样式自定义:

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);
}

这对我不起作用。我的课上有私有变量和获取方法
Shirish Herwade

6

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

为什么不在这里使用代码生成?例如,Eclipse将为您生成一个合理的toString实现。


5

另一个简单的方法是让您为您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生成吸气剂和吸气剂是完整的功能列表。


2

如果输出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);
    }
}

测试线束:

public static void main(String[] args) {
    A a = new A();
    a.x = 1;
    B b = new B();
    b.x=10;
    b.y=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;
}

0

除了@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;
}

0

我将得到如下答案:

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);

        }
    }

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.