Working with arrays in Java Reflection can be a bit tricky at times. Especially if you need to obtain the Class object for a certain type of array, like
int[]
etc. This text will discuss how to both create arrays and get their class objects via Java Reflection.Note: This text has been updated after reading Eyal Lupu's blog post
"Two Side Notes About Arrays and Reflection" which commented on the first edition of this text. The current edition takes his comments into consideration.
Here is a list of the topics covered:
- java.lang.reflect.Array
- Creating Arrays
- Accessing Arrays
- Obtaining the Class Object of an Array
- Obtaining the Component Type of an Array
java.lang.reflect.Array
Working with arrays via Java Reflection is done using thejava.lang.reflect.Array
class. Do not confuse this class with the java.util.Arrays
class in the Java Collections suite, which contains utility methods for sorting arrays, converting them to collections etc.Creating Arrays
Creating arrays via Java Reflection is done using thejava.lang.reflect.Array
class. Here is an example showing how to create an array:int[] intArray = (int[]) Array.newInstance(int.class, 3);This code sample creates an array of
int
. The first parameter int.class
given to theArray.newInstance()
method tells what type each element in the array should be of. The second parameter states how many elements the array should have space for.Accessing Arrays
It is also possible to access the elements of an array using Java Reflection. This is done via theArray.get(...)
and Array.set(...)
methods. Here is an example:int[] intArray = (int[]) Array.newInstance(int.class, 3); Array.set(intArray, 0, 123); Array.set(intArray, 1, 456); Array.set(intArray, 2, 789); System.out.println("intArray[0] = " + Array.get(intArray, 0)); System.out.println("intArray[1] = " + Array.get(intArray, 1)); System.out.println("intArray[2] = " + Array.get(intArray, 2));This code sample will print out this:
intArray[0] = 123 intArray[1] = 456 intArray[2] = 789
Obtaining the Class Object of an Array
One of the problems I ran into when implementing the script language in Butterfly DI Containerwas how to obtain theClass
object for arrays via Java Reflection. Using non-reflection code you can do like this:Class stringArrayClass = String[].class;Doing this using
Class.forName()
is not quite straightforward. For instance, you can access the primitive int
array class object like this:Class intArray = Class.forName("[I");The JVM represents an int via the letter
I
. The [
on the left means it is the class of an int
array I am interested in. This works for all other primitives too.For objects you need to use a slightly different notation:
Class stringArrayClass = Class.forName("[Ljava.lang.String;");Notice the
[L
to the left of the class name, and the ;
to the right. This means an array of objects with the given type.As a side note, you cannot obtain the class object of primitives using
Class.forName()
. Both of the examples below result in a ClassNotFoundException
:Class intClass1 = Class.forName("I"); Class intClass2 = Class.forName("int");I usually do something like this to obtain the class name for primitives as well as objects:
public Class getClass(String className){ if("int" .equals(className)) return int .class; if("long".equals(className)) return long.class; ... return Class.forName(className); }Once you have obtained the
Class
object of a type there is a simple way to obtain the Class
of an array of that type. The solution, or workaround as you might call it, is to create an empty array of the desired type and obtain the class object from that empty array. It's a bit of a cheat, but it works. Here is how that looks:Class theClass = getClass(theClassName); Class stringArrayClass = Array.newInstance(theClass, 0).getClass();This presents a single, uniform method to access the array class of arrays of any type. No fiddling with class names etc.
To make sure that the
Class
object really is an array, you can call the Class.isArray()
method to check:Class stringArrayClass = Array.newInstance(String.class, 0).getClass(); System.out.println("is array: " + stringArrayClass.isArray());
Obtaining the Component Type of an Array
Once you have obtained theClass
object for an array you can access its component type via theClass.getComponentType()
method. The component type is the type of the items in the array. For instance, the component type of an int[]
array is the int.class
Class
object. The component type of a String[]
array is the java.lang.String
Class
object.Here is an example of accessing the component type array:
String[] strings = new String[3]; Class stringArrayClass = strings.getClass(); Class stringArrayComponentType = stringArrayClass.getComponentType(); System.out.println(stringArrayComponentType);This example will print out the text "java.lang.String" which is the component type of the
String
array.
No comments:
Post a Comment