String.valueOf() behavior with char[] in List<char[]>

I was working with char[] and Collection with the below code :-

    char[] ch = { 'a', 'b', 'c' };
    List<char[]> chList = new ArrayList<char[]>();
    chList.add(new char[]{'d','e','f'});
    chList.add(new char[]{'g','h','i'});
    String chSt = String.valueOf(ch);
    String chListSt = chList.toString(); 
    System.out.println(chSt);  // outputs  abc
    System.out.println(chListSt); // outputs [[C@8288f50b, [C@b6d2b94b] instead [def, ghi]

Now what I observed above is :-

    String chSt = String.valueOf(ch);

I know the above code behaviour is correct for char[] in String.valueOf(), so for the above code abc is printed. Now consider the next line.

    String chListSt = chList.toString(); 

Also for the above code I know the toString() for List is defined in AbstractList and in the code of this overriden toString() I found buffer.append(next); which calls String.valueOf() method on the char[] which corresponds to next here.

So it should also print like [def, ghi], as in the direct case with char[] in the line String chSt = (String.valueOf(ch));

Why is this change in behaviour is there in both the cases while same method String.valueOf() is called on the char[]?

Jon Skeet
people
quotationmark

You're seeing the difference of calling different overloads of String.valueOf. Here's a simpler example:

public class Test {
    public static void main(String[] args) {
        char[] chars = { 'a', 'b', 'c' };
        System.out.println(String.valueOf(chars));  // abc
        Object object = chars;
        System.out.println(String.valueOf(object));  // [C@...
    }
}

The call you've found in StringBuffer or StringBuilder is just going to call String.valueOf(Object) - which then calls toString() on the array (after checking the reference isn't null). Arrays don't override toString in Java, hence the output you're getting.

people

See more on this question at Stackoverflow