Java:获取类的属性以构造字符串表示形式

假设我有一个这样的类(并且还进一步假设所有私有变量:

public class Item {
    private String _id = null;
    private String _name = null;
    private String _description = null;

        ...
}

现在,如果我想构建这个类的 toString() 表示形式,我会在 Item 类中执行如下操作:

@Override
public String toString() {
    return (_id + " " + _name + " " + _description);
}

但是,如果我在类中有15个私有变量呢?我是否必须像这样编写每个变量的名称?

理想情况下,我想通过迭代此类的私有变量列表并构造字符串表示来结束任务:

@Override
public String toString() {
    ArrayList<String> members = getClass().getMembers(); //Some method like this
    String string = "";
    for(...)
        string += members[i] + " ";
}

或者也许是toJSON方法,我仍然需要访问这些变量的名称。有什么建议吗?


答案 1

你可以做:

@Override
public String toString() {
  StringBuilder sb = new StringBuilder();
  sb.append(getClass().getName());
  sb.append(": ");
  for (Field f : getClass().getDeclaredFields()) {
    sb.append(f.getName());
    sb.append("=");
    sb.append(f.get(this));
    sb.append(", ");
  }
  return sb.toString();
}

不要使用字符串串联来构造来自 15 个数据成员的最终结果,尤其是在将调用很多的情况下。内存碎片和开销可能非常高。用于构造大型动态字符串。toString()StringBuilder

我通常让我的IDE(IntelliJ)简单地为我生成方法,而不是为此使用反射。toString()

另一个有趣的方法是使用龙目岛计划中@ToString注释

import lombok.ToString;

@ToString(excludes="id")
public class ToStringExample {
  private static final int STATIC_VAR = 10;
  private String name;
  private Shape shape = new Square(5, 10);
  private String[] tags;
  private int id;

  @ToString(callSuper=true, includeFieldNames=true)
  public static class Square extends Shape {
    private final int width, height;

    public Square(int width, int height) {
      this.width = width;
      this.height = height;
    }
  }
}

我发现这比Jakarta Commons toString构建器更可取,因为这种方法更具可配置性,并且它也是在编译时而不是运行时构建的。


答案 2

检查这个API org.apache.commons.lang.builder.ToStringBuilder,它提供了多种方法来创建toString usinf反射或不反射。也看看其他子类。