2

The code below would print array as a cryptic strings


NOTE: a similar question with Arrays.toString(arr) answer doesn't help, as in my case the type of variable passed to arr parameter will be Object and Arrays.toString(Object arr) method doesn't exist.

I tried to use something along Arrays.toString((?[])v) since at compilation time I will not know exact type of array, but this is not valid Java syntax.


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);
    }
  }
}

Output

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

Is there a way to print below result without a switch/case for every int/bool/double/string type?

[1, 2]
[1, 2, 3]
[true, false]
Pshemo
  • 122,468
  • 25
  • 185
  • 269
Alex Craft
  • 13,598
  • 11
  • 69
  • 133
  • Does this answer your question? [What's the simplest way to print a Java array?](https://stackoverflow.com/questions/409784/whats-the-simplest-way-to-print-a-java-array) – Progman Aug 05 '21 at 18:57
  • @Progman thanks, but no it doesn't solve this issue. As I don't know the exact type of array and `Arrays.toString(Object type)` doesn't compile. – Alex Craft Aug 05 '21 at 19:01
  • @Pshemo thanks, but it doesn't solve this issue. As I don't know the exact type of array and `Arrays.toString(Object type)` doesn't compile. – Alex Craft Aug 05 '21 at 19:02
  • 1
    @Pshemo The OP is trying to pass the fields that are arrays to `Arrays.toString`. – Unmitigated Aug 05 '21 at 19:07
  • 1
    Tried to clarify your question, hope I grasped core of your problem correctly. Feel free to rollback my edit if you don't agree with it. – Pshemo Aug 05 '21 at 19:51

3 Answers3

4
  1. You can use Class#isArray to check if the value is an array.

  2. You can use java.lang.reflect.Array#getLength and java.lang.reflect.Array#get to convert an Object to an Object array that can be passed to Arrays.toString.

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;
}
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
1

If you can live with your declared arrays using the primitive wrapper classes Integer and Boolean you could do something like this. I also added a constructor that populates the list directly.

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);
    }
  }
}

Output:

[1, 2]
[1, 2, 3]
[true, false]
RaffleBuffle
  • 5,396
  • 1
  • 9
  • 16
1

Most of what you want to do is done by Arrays.deepToString().

Try this.

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)));
    }
}

output:

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