【问题标题】:Output all of the values for variables in an object using reflection使用反射输出对象中变量的所有值
【发布时间】:2019-01-22 08:07:16
【问题描述】:

我想输出对象中变量的所有值。

目前我正在使用ReflectionToStringBuilder,但问题是它在输出集合时包含[,] 字符。

这是一个例子。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

public class Test 
{
    public int x = 10;

    public int y = 20;

    public String example = "This is some text, with a comma";

    public Collection<Integer> collection = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));

    public static void main(String args[])
    {
        System.out.println(ReflectionToStringBuilder.toString(new Test(),
                ToStringStyle.NO_FIELD_NAMES_STYLE));
    }
}

输出

Test@efb78af[10,20,This is some text, with a comma,[1, 2, 3, 4, 5]]

我尝试定义自己的ToStringStyle,但似乎没有任何选项可以删除方括号和逗号。

import org.apache.commons.lang3.builder.ToStringStyle;

public class ValueOnlyToStringStyle extends ToStringStyle
{
    public static final ToStringStyle VALUE_ONLY = new ValueOnlyToStringStyle();

    private static final long serialVersionUID = 1L;

    private ValueOnlyToStringStyle() 
    {
        super();
        this.setContentStart("");
        this.setFieldSeparator("  ");
        this.setFieldSeparatorAtStart(true);
        this.setContentEnd("");
        this.setUseClassName(false);
        this.setUseFieldNames(false);
        this.setArrayContentDetail(true);
        this.setArrayStart(" ");
        this.setArrayEnd(" ");
        this.setArraySeparator(" ");
        this.setDefaultFullDetail(true);
        this.setNullText("");
        this.setSizeStartText("");
        this.setSizeStartText("");
        this.setFieldNameValueSeparator(" ");
        this.setUseShortClassName(false);
        this.setUseIdentityHashCode(false);
        this.setSummaryObjectStartText(" ");
        this.setSummaryObjectEndText(" ");

    }
}

输出

10  20  This is some text, with a comma  [1, 2, 3, 4, 5]

我需要的是只获取没有添加字符的值。

10  20  This is some text, with a comma 1 2 3 4 5

如何做到这一点?

【问题讨论】:

  • [1, 2, 3, 4, 5]ArrayList::toString引起的,与ToStringStyle无关。
  • 这可能是个问题。有什么方法可以用ToStringStyle 实现我想要的吗?它需要输出我为集合显示的方式。
  • 我不熟悉ToStringStyle,也许你可以覆盖appendDetail(StringBuffer buffer, String fieldName, Collection&lt;?&gt; coll)
  • 嗯,您可能正在做某事。我会试一试,然后回复你。

标签: java apache-commons apache-commons-lang apache-commons-lang3


【解决方案1】:

我已经在我的机器上尝试过代码,它应该适用于您的示例。

class MyToStringStyle extends ToStringStyle {
    public MyToStringStyle() {
        setFieldSeparator(" ");
        setUseFieldNames(false);
        setUseIdentityHashCode(false);
        setUseClassName(false);
        setContentStart("");
        setContentEnd("");
    }

    @Override
    protected void appendDetail(StringBuffer buffer, String fieldName, Collection<?> coll) {
        if (coll.isEmpty()) return;
        Iterator iter = coll.iterator();
        buffer.append(iter.next());
        while (iter.hasNext()) {
            buffer.append(" ").append(iter.next());
        }
    }
}

【讨论】:

  • 刚刚试了一下。我也覆盖了Map 之一。效果很好,谢谢!
  • 这个解决方案解决了我在选择对象问题的必要部分时遇到的问题,我喜欢它,它非常简单而且写得很好
【解决方案2】:

我决定编辑代码,因为我已经构建了一个自定义 ReflectionToStringBuilder 方法。方法如下:

public static String toString(Object object) {
    Class<?> clazz = object.getClass();

    Field[] fields = clazz.getDeclaredFields();

    StringBuilder stringBuilder = new StringBuilder();

    for (Field field : fields) {

        try {
            field.setAccessible(true);
            Object value = field.get(object);

            // check if the value is actually a list
            if (List.class.isAssignableFrom(value.getClass())) {
                // this for some reason gives the unchecked cast warning, but we actually are
                // checking it so don't worry!
                @SuppressWarnings("unchecked")
                List<Object> list = (List<Object>) value;

                for (Object element : list) {
                    stringBuilder.append(element.toString()).append(" ");
                }
            } else if (value.getClass().isArray()) {
                Object[] array = (Object[]) value;

                for (Object element : array) {
                    stringBuilder.append(element.toString()).append(" ");
                }
            } else {
                stringBuilder.append(value.toString()).append(" ");
            }

        } catch (IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    return stringBuilder.toString();
}

我已经测试过了,效果很好。

我的班级:

int x = 0;

String string = "string0";

List<String> stringList = Arrays.asList("string1");

String[] stringArray = {"string3", "string4"};

public static void main(String[] args) {
    Test test = new Test();
    System.out.println(toString(test));
}

输出:

0 string0 string1 string3 string4 

【讨论】:

  • 如果我的一个对象的字符串中包含“,”怎么办?例如。 String sentence = "This is some text, with a comma"。在这种情况下,我不希望它被删除。
  • @Michael ReflectionToStringBuilder 在创建字符串时是否将字符串放在引号内?
  • 我已经更新了我的问题。不,它不会用引号引起来。
  • @Michael 您是否测试过它不会在引号中或只是假设?他们没有把它放在引号中是没有意义的,因为这样看起来逗号也在分隔一些它不是的东西。 ://
  • 我在运行后添加了输出。它不在引号中。 Test 类的代码正是我运行的。
猜你喜欢
  • 1970-01-01
  • 2017-09-24
  • 1970-01-01
  • 2020-03-07
  • 2012-01-28
  • 2015-11-21
  • 2014-03-03
  • 2011-01-13
  • 1970-01-01
相关资源
最近更新 更多