如何打印存储为对象变量的任何类型的数组?

How to print array of any type stored as Object variable?

下面的代码会将数组打印为神秘字符串


注意: 带有 Arrays.toString(arr) 答案的 similar question 没有帮助,因为在我的例子中,传递给 arr 的变量类型参数将为 Object 并且 Arrays.toString(Object arr) 方法不存在。

我尝试使用 Arrays.toString((?[])v) 中的一些东西,因为在编译时我不知道 确切的 类型的数组,但这是无效的 Java 语法.


import java.io.*;
import java.lang.reflect.*;
import java.util.ArrayList;

public class Play {
  public ArrayList<Integer> list = new ArrayList<>();
  public int[] iarray            = {1, 2, 3};
  public boolean[] barray        = {true, false};

  public static void main(String[] args) throws IOException, IllegalAccessException {
    Play o = new Play();
    // Is it possible to initialize it in constructor as {1, 2}?
    o.list.add(1);
    o.list.add(2);

    Field[] fields = o.getClass().getDeclaredFields();
    for (Field field : fields) {
      Object v = field.get(o);
      // Object s = v.getClass().getName().startsWith("[") ? Arrays.toString((?[])v) : v;
      System.out.println(v);
    }
  }
}

输出

[1, 2]
[I@3498ed
[Z@1a407d53

有没有办法在每个 int/bool/double/string 类型 不带 switch/case 的情况下打印下面的结果

[1, 2]
[1, 2, 3]
[true, false]
  1. 您可以使用Class#isArray检查值是否为数组。

  2. 您可以使用 java.lang.reflect.Array#getLengthjava.lang.reflect.Array#getObject 转换为可以传递给 Arrays.toStringObject 数组.

Demo

public static void main(String[] args) throws IOException, IllegalAccessException {
    Play o = new Play();
    o.list.add(1);
    o.list.add(2);

    Field[] fields = o.getClass().getDeclaredFields();
    for (Field field: fields) {
        Object v = field.get(o);
        if (v.getClass().isArray()) System.out.println(Arrays.toString(toArray(v)));
        else System.out.println(v);
    }
}

private static Object[] toArray(Object obj) {
    int len = Array.getLength(obj);
    Object[] res = new Object[len];
    for (int i = 0; i < len; i++) res[i] = Array.get(obj, i);
    return res;
}

如果您可以使用原始包装器 类 IntegerBoolean 来处理声明的数组,那么您可以这样做。我还添加了一个直接填充列表的构造函数。

public class Play {
  public ArrayList<Integer> list = new ArrayList<>();
  public Integer[] iarray            = {1, 2, 3};
  public Boolean[] barray        = {true, false};

  public Play(Integer... vals) {
    list.addAll(Arrays.asList(vals));
  }

  public static void main(String[] args) throws IOException, IllegalAccessException {
    Play o = new Play(1, 2);

    Field[] fields = o.getClass().getDeclaredFields();
    for (Field field : fields) {
      Object v = field.get(o);
      if(v.getClass().isArray() && !v.getClass().getComponentType().isPrimitive())
        System.out.println(Arrays.toString((Object[])v));
      else
        System.out.println(v);
    }
  }
}

输出:

[1, 2]
[1, 2, 3]
[true, false]

大部分您想做的事情都由 Arrays.deepToString() 完成。

试试这个。

public class Play {
    public List<Integer> list = List.of(0, 1);
    public int ivalue = 999;
    public int[] iarray = {1, 2, 3};
    public int[][] iarray2 = {{1}, {2, 3}};
    public boolean[] barray = {true, false};
    public String[] sarray = {"A", "B"};
    public String[][] sarray2 = {{"A", "B"}, {"C"}};

    static String toString(Object obj) {
        String s = Arrays.deepToString(new Object[] {obj});
        return s.substring(1, s.length() - 1);
    }

    public static void main(String[] args) throws IllegalAccessException {
        Play o = new Play();
        for (Field field : o.getClass().getDeclaredFields())
            System.out.println(field.getName() + " = " + toString(field.get(o)));
    }
}

输出:

list = [0, 1]
ivalue = 999
iarray = [1, 2, 3]
iarray2 = [[1], [2, 3]]
barray = [true, false]
sarray = [A, B]
sarray2 = [[A, B], [C]]