Java 打印类中的所有变量值

Java 打印类中的所有变量值,java,reflection,Java,Reflection,我有一个类,包含一个人的信息,看起来像这样: public class Contact { private String name; private String location; private String address; private String email; private String phone; private String fax; public String toString() { // Som

我有一个类,包含一个人的信息,看起来像这样:

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
public class Contact {
    private String name;
    private String location;
    private String address;
    private String email;
    private String phone;
    private String fax;

    // Getters and setters.
}
我希望
toString()
为所有变量返回
this.name+“-”+this.locations+…
。我试图使用反射实现它,如中所示,但我无法打印实例变量


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

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

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

来源:


既然有开源软件已经很好地完成了这项工作,为什么还要重新发明轮子呢

apache和Java都支持一些非常灵活的构建器模式

对于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(); 
}
您可以尽可能使用非默认设置“样式化”打印输出,甚至使用自己的样式自定义打印输出

我没有亲自尝试SpringAPI,但它看起来非常相似

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

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

1.按Alt+Shift+S

2.选择“生成toString()…”

享受吧!您可以拥有toString()s的任何模板


这也适用于getter/setter。

除了@cletus answer,您必须获取所有模型字段(上层层次结构)并设置
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;
}
@覆盖
公共字符串toString(){
StringBuilder结果=新建StringBuilder();
字符串newLine=System.getProperty(“line.separator”);
append(getClass().getSimpleName());
结果。追加(“{”);
结果.追加(换行符);
列表字段=getAllModelFields(getClass());
用于(字段:字段){
结果。追加(“”);
试一试{
append(field.getName());
结果。追加(“:”);
字段。setAccessible(true);
result.append(field.get(this));
}捕获(非法访问例外){
//系统错误打印项次(ex);
}
结果.追加(换行符);
}
result.append(“}”);
结果.追加(换行符);
返回result.toString();
}
私有列表getAllModelFields(类aClass){
列表字段=新的ArrayList();
做{
Collections.addAll(fields,aClass.getDeclaredFields());
aClass=aClass.getSuperclass();
}while(aClass!=null);
返回字段;
}

另一个简单的方法是让您生成
toString
方法

为此:

  • 只需将
    Lombok
    添加到项目中即可
  • 将注释
    @ToString
    添加到类的定义中
  • 编译你的类/项目,它就完成了
  • 例如,在您的案例中,您的类将如下所示:

    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
    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)
    
    更多的细节


    NB:您也可以让
    Lombok
    为您生成完整的功能列表。

    如果
    ReflectionStringBuilder.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);
        }
    }
    

    我会得到以下答案:

    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);
    
            }
        }
    
    }
    
    import java.io.IOException;
    导入java.io.Writer;
    导入java.lang.reflect.Array;
    导入java.lang.reflect.Field;
    导入java.util.HashMap;
    导入java.util.Map;
    公共类findclass{
    公共静态void main(字符串[]args)引发异常,IllegalAccessException{
    新findclass().findclass(新对象(),“对象名”);
    新的findclass().findclass(1213,“int”);
    新的findclass().findclass(“ssdfs”,“String”);
    }
    public Mapmap=new HashMap();
    public void findclass(对象c,字符串名)抛出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);
    返回;}
    map.put(c.getClass().getName()+“@”+Integer.toHexString(c.hashCode()),name);
    类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);
    返回;
    }
    if(te.isArray()){
    如果(te==int[].class | | te==char[].class | | te==double[].class | | te==float[].class | | te==byte[].class | te==long[].class | te==boolean[].class){
    布尔点标志=真;
    for(int i=0;i