Use System.out.println(Arrays.toString(arr)) (import java.util.Arrays). It prints [3, 1, 4, 1, 5] instead of the [I@-plus-hash you get from println(arr). For a 2-D array, use Arrays.deepToString(grid).
Java arrays don't override toString(), so System.out.println(arr) falls back to Object.toString() and prints the array's type code, an @ and a hex hash code, something like [I@ followed by eight hex digits. [I means "array of int", and the hash has nothing to do with the contents and isn't guaranteed to be the same from one run to the next. The fix lives in java.util.Arrays, and this page covers it along with nested arrays, custom separators, loops, and the two cases that already print well: lists and char[]. Each example runs on this page: hit Run, then edit the code and run it again.
1Arrays.toStringRecommended
Arrays.toString(arr) returns the elements in square brackets, separated by a comma and a space. It has an overload for every primitive array type (int[], double[], boolean[] and so on) plus one for Object[], which calls String.valueOf on each element. It has been in the JDK since Java 5 and is the standard answer for debugging and logging.
Output
Prints [3, 1, 4, 1, 5], [Ada, Linus, Grace], [4.5, 12.0, 7.25] and [true, false], then [] for the empty array and null for the null reference (no exception). The last line prints true: the default text of an int[] really does start with [I@. The snippet checks only that prefix because the hash after it isn't guaranteed to stay the same. Strings print without quotes, so Arrays.toString can't tell you whether an element is "null" or null.
22-D arrays: Arrays.deepToString
A 2-D array in Java is an array of arrays, so Arrays.toString(grid) only formats the outer level and prints each row with the useless default text. Arrays.deepToString recurses into every nested array, however deep. It takes an Object[], which any array of arrays is. For a grid you want to read, print one row per line with a loop and Arrays.toString on each row.
Output
Prints true (the shallow version starts with [[I@), then [[1, 2, 3], [4, 5, 6]] and [[en, Hello], [es, Hola]], then the grid as [1, 2, 3] and [4, 5, 6] on separate lines. deepToString also works on a 1-D String[] or Integer[], but not on an int[], which is not an Object[], so that call doesn't compile. For how the grid literal above is built, see declare and initialize an array.
3Your own separator: String.join and Collectors.joining
Arrays.toString always uses brackets and , . When you want plain Ada, Linus, Grace or any other layout, build the string yourself. For a String[], String.join(separator, arr) (Java 8+) is one call. It doesn't accept an int[], so for numbers turn the array into a stream, convert each element with mapToObj(String::valueOf) and collect with Collectors.joining, which also takes an optional prefix and suffix. Joining gets its own page in join a list into a string.
Output
Prints Ada, Linus, Grace, Ada | Linus | Grace, 3 1 4 1 5 and {3, 1, 4, 1, 5}, then each name on its own line. Arrays.stream(arr).forEach(System.out::println) is the stream version of a for-each loop; it reads well at the end of a pipeline that filters or maps first. Older answers reach for Guava's Joiner or Apache Commons' ArrayUtils.toString. Since Java 8 the JDK covers both without a dependency.
4A for-each loop
A loop is the most flexible option and works on every Java version. The enhanced for (String name : names) loop prints one element per line. To keep everything on one line, use System.out.print and write the separator before every element except the first. When you need the index too, switch to the classic index loop and format each line with printf.
Output
Prints Ada, Linus, Grace on three lines, then 3, 1, 4, 1, 5, then 0: Ada, 1: Linus and 2: Grace. The final System.out.println() after the second loop ends the line, otherwise the next output would continue on it. In printf, %n is the platform line separator. This snippet needs no imports at all.
5Lists print fine, and char[] is special
Unlike arrays, every standard collection overrides toString(), so a List<String> or ArrayList prints its contents with a plain println. If you already hold a String[], Arrays.asList(arr) wraps it in a list view without copying (more in convert an array to a list). The one array that prints as text is char[], because PrintStream has a dedicated println(char[]) overload. That overload is the only reason it works.
Output
Prints [Java, Go, Python], [90, 85, 77] and [Ada, Linus, Grace], then Java from the char[]. The check prints true: once the array is concatenated into a string, println receives a String and the array was already turned into [C@ plus a hash. The last two lines show the fixes, chars: [J, a, v, a] and chars: Java. List.of needs Java 9+; don't use Arrays.asList on an int[], which is covered in the FAQ below.
6Which should you use?
| Method | Prints | Needs | Best for |
|---|---|---|---|
| Arrays.toString(arr) | [3, 1, 4, 1, 5] | Java 5+ | Debugging and logging: the default |
| Arrays.deepToString(arr) | [[1, 2, 3], [4, 5, 6]] | Java 5+ | 2-D and deeper arrays |
| String.join(", ", arr) | Ada, Linus, Grace | Java 8+, String[] | Custom separator, no brackets |
| Collectors.joining(sep, pre, suf) | {3, 1, 4, 1, 5} | Java 8+ | Numbers in a custom format |
| for (T x : arr) | Whatever you write | Any version | Per-element formatting, one per line |
| System.out.println(arr) | [I@ and a hash | Any version | Nothing, except a char[] |
Frequently asked questions
Why does System.out.println(array) print something like [I@1b6d3586?
Arrays inherit toString() from Object, which returns the class name, an @ and the hex identity hash code. The class name of an int[] is [I, a String[] is [Ljava.lang.String;, a double[] is [D and an int[][] is [[I. The hash says nothing about the contents and isn’t guaranteed to be the same between runs. Wrap the array in Arrays.toString(arr) to print the elements.
How do I print a 2-D array in Java?
Use Arrays.deepToString(grid), which prints [[1, 2, 3], [4, 5, 6]] for a 2x3 int[][]. Arrays.toString(grid) only formats the outer array, so each row comes out as [I@ plus a hash. To print one row per line, loop over the rows: for (int[] row : grid) System.out.println(Arrays.toString(row));.
How do I print an array without the brackets and commas?
For a String[], use String.join(" ", arr) with whatever separator you want. For an int[] or other numbers, use Arrays.stream(arr).mapToObj(String::valueOf).collect(Collectors.joining(" ")). A for loop with System.out.print also works on every Java version.
Why does Arrays.toString print MyClass@... for my objects?
For an object array, Arrays.toString calls each element’s own toString(), and a class that doesn’t override it prints its name and hash code. Override toString() in your class, or use a record (Java 16+), which generates one: an array of record Point(int x, int y) prints as [Point[x=1, y=2], Point[x=3, y=4]].
Why does Arrays.asList(intArray) not print the numbers?
Arrays.asList is generic, and generics can’t hold primitives, so passing an int[] gives a List<int[]> with one element (its size() is 1), which prints as a nested [I@ hash. Box the values instead: Arrays.stream(nums).boxed().toList() (Java 16+) prints [3, 1, 4], or declare the array as Integer[] from the start.
Why does println print a char[] as text but not other arrays?
PrintStream has an overload println(char[] x) that prints the characters as a string, so System.out.println(word) prints Java. No other array type has one. The overload only applies when the char[] is the whole argument: "chars: " + word converts the array with the default toString() first and prints [C@ plus a hash. Use new String(word) or Arrays.toString(word) in that case.
Run it yourself
Open any of these in the full Java editor to tweak, run and share them.
Java playground