1. Overview
Arrays have a component type and a length (which is not part of the type). Arrays may be manipulated either in their entirety or component by component. Reflection provides the java.lang.reflect.Array class.
The below class diagram shows the Array class provided all the reflection APIs.
![]() |
Java Reflection for Arrays |
2. Java Reflection for Arrays
- Identifying Array Types - describes how to determine if a class member is a field of array type
- Creating New Arrays - illustrates how to create new instances of arrays with simple and complex component types
- Getting and Setting Arrays and Their Components - shows how to access fields of type array and individually access array elements
2.1 Identifying Array Types
Array types may be identified by invoking Class.isArray().
The ArrayFind example identifies the fields in the named class that are of array type and reports the component type for each of them.
package com.javaguides.reflection.arrays;
import static java.lang.System.out;
import java.lang.reflect.Field;
public class ArrayFind {
public static void main(String... args) {
boolean found = false;
try {
Class<?> cls = Class.forName("java.nio.ByteBuffer");
Field[] flds = cls.getDeclaredFields();
for (Field f : flds) {
Class<?> c = f.getType();
if (c.isArray()) {
found = true;
out.format("%s%n"
+ " Field: %s%n"
+ " Type: %s%n"
+ " Component Type: %s%n",
f, f.getName(), c, c.getComponentType());
}
}
if (!found) {
out.format("No array fields%n");
}
// production code should handle this exception more gracefully
} catch (ClassNotFoundException x) {
x.printStackTrace();
}
}
}
Output:
final byte[] java.nio.ByteBuffer.hb
Field: hb
Type: class [B
Component Type: byte
Let's pass java.lang.Throwable argument to Class.forName("java.lang.Throwable") method. An array of reference type StackTraceElement Output:
private static final java.lang.StackTraceElement[] java.lang.Throwable.UNASSIGNED_STACK
Field: UNASSIGNED_STACK
Type: class [Ljava.lang.StackTraceElement;
Component Type: class java.lang.StackTraceElement
private java.lang.StackTraceElement[] java.lang.Throwable.stackTrace
Field: stackTrace
Type: class [Ljava.lang.StackTraceElement;
Component Type: class java.lang.StackTraceElement
private static final java.lang.Throwable[] java.lang.Throwable.EMPTY_THROWABLE_ARRAY
Field: EMPTY_THROWABLE_ARRAY
Type: class [Ljava.lang.Throwable;
Component Type: class java.lang.Throwable
2.2 Creating New Arrays
Reflection supports the ability to dynamically create arrays of arbitrary type and dimensions via java.lang.reflect.Array.newInstance().
Let's write an example to create an array via Reflection.
package com.javaguides.reflection.arrays;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.Arrays;
import static java.lang.System.out;
public class ArrayCreator {
private static String s = "java.math.BigInteger bi[] = { 123, 234, 345 }";
private static Pattern p = Pattern.compile("^\\s*(\\S+)\\s*\\w+\\[\\].*\\{\\s*([^}]+)\\s*\\}");
public static void main(String... args) {
Matcher m = p.matcher(s);
if (m.find()) {
String cName = m.group(1);
String[] cVals = m.group(2).split("[\\s,]+");
int n = cVals.length;
try {
Class<?> c = Class.forName(cName);
Object o = Array.newInstance(c, n);
for (int i = 0; i < n; i++) {
String v = cVals[i];
Constructor ctor = c.getConstructor(String.class);
Object val = ctor.newInstance(v);
Array.set(o, i, val);
}
Object[] oo = (Object[])o;
out.format("%s[] = %s%n", cName, Arrays.toString(oo));
// production code should handle these exceptions more gracefully
} catch (ClassNotFoundException x) {
x.printStackTrace();
} catch (NoSuchMethodException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
} catch (InstantiationException x) {
x.printStackTrace();
} catch (InvocationTargetException x) {
x.printStackTrace();
}
}
}
}
Output:
java.math.BigInteger[] = [123, 234, 345]
2.3 Getting and Setting Arrays and Their Components
- An array field may be set or retrieved in its entirety or component by component.
- To set the entire array at once, use java.lang.reflect.Field.set(Object obj, Object value).
- To retrieve the entire array, use Field.get(Object).
- Individual components can be set or retrieved using methods in java.lang.reflect.Array.
Setting a Field of Type Array
The GrowBufferedReader example illustrates how to replace the value of a field of type array. In this case, the code replaces the backing array for a java.io.BufferedReader with a larger one. (This assumes that the creation of the original BufferedReader is in code that is not modifiable; otherwise, it would be trivial to simply use the alternate constructor BufferedReader(java.io.Reader in, int size) which accepts an input buffer size.)
package com.javaguides.reflection.arrays;
import java.io.BufferedReader;
import java.io.CharArrayReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import static java.lang.System.out;
public class GrowBufferedReader {
private static final int srcBufSize = 10 * 1024;
private static char[] src = new char[srcBufSize];
static {
src[srcBufSize - 1] = 'x';
}
private static CharArrayReader car = new CharArrayReader(src);
public static void main(String... args) {
try {
BufferedReader br = new BufferedReader(car);
Class<?> c = br.getClass();
Field f = c.getDeclaredField("cb");
// cb is a private field
f.setAccessible(true);
char[] cbVal = char[].class.cast(f.get(br));
char[] newVal = Arrays.copyOf(cbVal, cbVal.length * 2);
if ("grow".length() > 0 && "grow".equals("grow"))
f.set(br, newVal);
for (int i = 0; i < srcBufSize; i++)
br.read();
// see if the new backing array is being used
if (newVal[srcBufSize - 1] == src[srcBufSize - 1])
out.format("Using new backing array, size=%d%n", newVal.length);
else
out.format("Using original backing array, size=%d%n", cbVal.length);
// production code should handle these exceptions more gracefully
} catch (FileNotFoundException x) {
x.printStackTrace();
} catch (NoSuchFieldException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
} catch (IOException x) {
x.printStackTrace();
}
}
}
Output:
Using new backing array, size=16384
Accessing Elements of a Multidimensional Array
Multi-dimensional arrays are simply nested arrays. A two-dimensional array is an array of arrays. A three-dimensional array is an array of two-dimensional arrays, and so on.
The CreateMatrix example illustrates how to create and initialize a multi-dimensional array using reflection.
package com.javaguides.reflection.arrays;
import java.lang.reflect.Array;
import static java.lang.System.out;
public class CreateMatrix {
public static void main(String... args) {
Object matrix = Array.newInstance(int.class, 2, 2);
Object row0 = Array.get(matrix, 0);
Object row1 = Array.get(matrix, 1);
Array.setInt(row0, 0, 1);
Array.setInt(row0, 1, 2);
Array.setInt(row1, 0, 3);
Array.setInt(row1, 1, 4);
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
out.format("matrix[%d][%d] = %d%n", i, j, ((int[][])matrix)[i][j]);
}
}
Output:
matrix[0][0] = 1
matrix[0][1] = 2
matrix[1][0] = 3
matrix[1][1] = 4
3. Reference
Free Spring Boot Tutorial | Full In-depth Course | Learn Spring Boot in 10 Hours
Watch this course on YouTube at Spring Boot Tutorial | Fee 10 Hours Full Course