Java toString() using reflection?

2022-08-31 16:33:55

前几天,我通过手动将类的每个元素写出到一个字符串中,为Java中的一个类编写了一个toString(),我突然想到,使用反射,可以创建一个可以在所有类上使用的通用toString()方法。即,它将找出字段名称和值,并将它们发送到字符串。

获取字段名称相当简单,这是一位同事想出的:

public static List initFieldArray(String className) throws ClassNotFoundException {

    Class c = Class.forName(className);
    Field field[] = c.getFields();
    List<String> classFields = new ArrayList(field.length);

    for (int i = 0; i < field.length; i++) {
        String cf = field[i].toString();
        classFields.add(cf.substring(cf.lastIndexOf(".") + 1));
    }

    return classFields;
}

使用工厂,我可以通过存储一次字段来降低性能开销,这是第一次调用 toString() 时。但是,查找值可能会花费更多。

由于反射的性能,这可能更具假设性,然后实用性。但我对反思的想法以及我如何利用它来改进我的日常编程很感兴趣。


答案 1

Apache commons-lang ReflectionToStringBuilder为你做这件事。

import org.apache.commons.lang3.builder.ReflectionToStringBuilder

// your code goes here

public String toString() {
   return ReflectionToStringBuilder.toString(this);
}

答案 2

另一种选择,如果你对JSON没问题,那就是谷歌的GSON库。

public String toString() {
    return new GsonBuilder().setPrettyPrinting().create().toJson(this);
}

它将为你做反思。这将生成一个漂亮且易于阅读的 JSON 文件。易于阅读的相对,非技术人员可能会发现JSON令人生畏。

您也可以将GSONBuilder设置为成员变量,如果您不想每次都将其更新。

如果您有无法打印的数据(如流)或您只是不想打印的数据,则只需将@Expose标记添加到要打印的属性中,然后使用以下行。

 new GsonBuilder()
.setPrettyPrinting()
.excludeFieldsWithoutExposeAnnotation()
.create()
.toJson(this);