Previous in the Series
Current Tutorial
Working with Arrays
Next in the Series

Previous in the Series: Invoking Constructors

Next in the Series: Working with Enumerations

Working with Arrays

Arrays are implemented in the Java virtual machine. The only methods on arrays are those inherited from Object. The length of an array is not part of its type; arrays have a length field which is accessible via Array.getLength(Object).

Reflection provides methods for accessing array types and array component types, creating new arrays, and retrieving and setting array component values.

 

Identifying Array Types

Array types may be identified by invoking Class.isArray().

You can get the exact type of the internal array on a String object with the following code.

Class<?> c = String.class;
Field field = c.getDeclaredField("value");

Class<?> fieldType = field.getType();
boolean isArray = fieldType.isArray();
System.out.println("isArray = " + isArray);

Class<?> elementType = fieldType.getComponentType();
System.out.println("elementType = " + elementType);

Running the previous code prints the following.

isArray = true
elementType = byte

 

Creating New Arrays

Just as in non-reflective code, reflection supports the ability to dynamically create arrays of arbitrary type and dimensions via java.lang.reflect.Array.newInstance().

The Array class contains a collection of static method to get reflective information on arrays, as well as to set and read the elements on any array.

Let us consider the following code.

int length = 10;

Object o = Array.newInstance(int.class, 10);
boolean isArray = o.getClass().isArray();
System.out.println("isArray = " + isArray);
Class<?> componentType = o.getClass().getComponentType();
System.out.println("componentType = " + componentType);
int reflectiveLength = Array.getLength(o);
System.out.println("reflectiveLength = " + reflectiveLength);

for (int i = 0; i < reflectiveLength; i++) {
    Array.set(o, i, 2*i);
}
System.out.println(Arrays.toString((int[])o));

Let us comment this code line by line.

  1. Array.newInstance(int.class, 10): creates a new instance of an array of 10 int.
  2. o.getClass().isArray(): check if the corresponding class is an array class.
  3. o.getClass().getComponentType(): returns the type of the components of this array. In this case, it is int.
  4. Array.getLength(o): returns the length of this array.
  5. Array.set(o, i, 2*i): reflectively set the i th element of the array o to the value 2*i. You can also reflectively read the i th element of the array o with the Array.get(o, i) method call.

Note that the Array class has methods to set primitive values without boxing or unboxing. For example, you can use Array.setDouble() and Array.getDouble() to set and get the elements of an array of double.

There are two elements to consider when using these methods.

  1. Calling a setFloat() method with a Float object instead of a float primitive type will throw an IllegalArgumentException.
  2. Calling Arrays.setInt() and passing an array of longs is OK, as there is no loss of precision when converting an int to a long. The contrary is illegal. You cannot call Arrays.setLong(), passing an array of ints, as it would lead to a loss of precision due to the narrowing of your long.

Running the previous code prints the following.

isArray = true
componentType = int
reflectiveLength = 10
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

Note that trying to read or write elements at an index greater than the length of this array will throw an ArrayIndexOutOfBoundsException.


Last update: July 25, 2024


Previous in the Series
Current Tutorial
Working with Arrays
Next in the Series

Previous in the Series: Invoking Constructors

Next in the Series: Working with Enumerations