为ToString实现共享多个类

时间:2016-06-01 17:19:01

标签: java tostring

我使用下面的代码有多个pojo类。

public class ToStringImpl {

public String toString(){
      StringBuilder result = new StringBuilder();
      String newLine = "\n";


      result.append( this.getClass().getName() );
      result.append( " Data {" );
      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();
}

}

如何从不同的班级打电话给上课? 假设我有pojo类,称为客户,商店,库存

public class Customer {

private String name;
private String address;

...getter...setter...

public String toString(){

    ToStringImpl log = new ToStringImpl();
    //how do I pass different classes here?
    return log.toString();
}

}

public class Store {

private String logo;
private String type;

....getter...setter...
}

public class Inventory {

private boolean isAvailable;
private long index;

...getter...setter
}

每个班级如何通过不同的课程?或者,如果有更好的方法来做到这一点?或者最好将toString创建为接口并在每个类中实现它并将其作为构造函数传递?

3 个答案:

答案 0 :(得分:3)

您可以做的是使toString()类中的ToStringImpl方法保持静态。我不会将其称为toString(),但将其更改为getClassString()

示例

public static String getClassString(Object o)
{
    StringBuilder result = new StringBuilder();
    String newLine = "\n";

    result.append(o.getClass().getName());
    result.append(" Data {");
    result.append(newLine);

    // determine fields declared in this class only (no fields of
    // superclass)
    Field[] fields = o.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(o));
        }
        catch (IllegalAccessException ex)
        {
            System.out.println(ex);
        }
        result.append(newLine);
    }
    result.append("}");

    return result.toString();
}

然后在你的POJO课程中,用:

调用它
public String toString()
{
    // how do I pass different classes here?
    // by passing the 'this' reference
    return ToStringImpl.getClassString(this);
}

答案 1 :(得分:1)

已经有一个库可以做到这一点。在apache-commons库中查找ToStringBuilder,你的域对象的toString方法看起来像:

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

在我看来,最好的计划是撕掉本土代码并放入apache-commons,或者使用Project Lombok。如果你必须重新发明这个轮子,那么复制ToStringBuilder的使用静态方法并将对象作为参数打印的例子是合理的。

ToStringBuilder包含一个功能,允许您限制打印哪些字段,您自己的代码应该为了您自己的理智而做类似的事情。 toString方法用于打印出调试和记录的信息。如果您只是获取所有字段,例如您发布的代码,那么每次在日志条目中调用toString时,它都会转储整个对象的内容,并且您将拥有一些不可读的内容,它将填满您的日志并减慢您的应用程序写入所有这些信息。

你是这里信息的消费者,使它成为有用而不是压倒性的东西。

答案 2 :(得分:0)

当您覆盖某个方法时,例如Object#toString(),您只能覆盖该类。您可以执行以下操作之一:

  • toString()添加到可能需要它的每个类中,然后只需在该对象上调用toString()即可。 (不推荐)
  • 在你想要的每个类上扩展你的ToStringImpl并在对象上调用toString()。
  • 使ToStringImpl#toString()为静态并将对象作为参数传递(推荐),例如:

    public static void objectToString(Object ob){
       //your code here, just replace "this" with "ob"
    }