Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different behaviour on Arrays.asList(T...) using ternary

Tags:

java

A colleague came across this behaviour while using ternary operator inside the Arrays.asList(T...)

public static void main(String[] args) throws Exception {              
    System.out.println(Arrays.asList(new String[]{"2"}));
    System.out.println(Arrays.asList(false? new int []{2} :new String[]{"2"}));
}

The first sout prints: [2]

The second one prints: [[Ljava.lang.String;@36baf30c]

The java version used is java 8.

Shouldn't the second sout print the same result as the first?

like image 295
Michail Avatar asked Sep 11 '20 20:09

Michail


2 Answers

Arrays.asList has varargs parameter, and it can be called in two ways:

  1. you pass it an array of some kind of objects and those objects become the contents of the list.
  2. you pass zero or more objects and they are put into an array, and then they become the contents of your list.

The first version of your code

Arrays.asList(new String[]{"2"}))

is interpreted as you passing a String array in place of the varargs argument to asList, so you get a String list containing the contents of the array, which is the element "2".

In the second version, the type of the expression

(false? new int []{2} :new String[]{"2"})

is Object, since int[] and String[] have no other common base type, and an int array cannot be interpreted as an Object array.

So your asList call resolves to a varargs call with one Object argument.

That gives you a list containing one element, where that element itself is your array.

like image 70
khelwood Avatar answered Sep 22 '22 02:09

khelwood


The parameter of Arrays.asList is a varargs parameter, T..., which is syntactic sugar that lets you call it in either of two ways:

  • You can call it with an expression of type T[], in which case the result of that expression is passed directly into Arrays.asList.
    • This is what you're doing in your first case: the argument has type String[], so T is String and the array is passed into Arrays.asList.
  • You can call it with zero or more expressions of type T, in which case the results of those expressions get bundled up into an array which gets passed into Arrays.asList.
    • This is what you're doing in your second case: the argument has type Object, so T is Object and a single-element array containing that argument gets passed into Arrays.asList.

This is because int isn't a subtype of Object, so int[] isn't a subtype of Object[].

like image 26
ruakh Avatar answered Sep 20 '22 02:09

ruakh