Just as in non-reflective code, an array field may be set or retrieved in its entirety or component by component. To set the entire array at once, usejava.lang.reflect.Field.set(Object obj, Object value). To retrieve the entire array, useField.get(Object). Individual components can be set or retrieved using methods injava.lang.reflect.Array.
Arrayprovides methods of the formsetFoo()andgetFoo()for setting and getting components of any primitive type. For example, the component of anintarray may be set withArray.setInt(Object array, int index, int value)and may be retrieved withArray.getInt(Object array, int index).These methods support automatic widening of data types. Therefore,
Array.getShort()may be used to set the values of anintarray since a 16-bitshortmay be widened to a 32-bitintwithout loss of data; on the other hand, invokingArray.setLong()on an array ofintwill cause anIllegalArgumentExceptionto be thrown because a 64-bitlongcan not be narrowed to for storage in a 32-bitintwith out loss of information. This is true regardless of whether the actual values being passed could be accurately represented in the target data type. The Java Language Specification, Third Edition, sections 5.1.2 and 5.1.3 contains a complete discussion of widening and narrowing conversions.The components of arrays of reference types (including arrays of arrays) are set and retrieved using
Array.set(Object array, int index, int value)andArray.get(Object array, int index).Setting a Field of Type Array
The
example illustrates how to replace the value of a field of type array. In this case, the code replaces the backing array for aGrowBufferedReaderjava.io.BufferedReaderwith a larger one. (This assumes that the creation of the originalBufferedReaderis in code that is not modifiable; otherwise, it would be trivial to simply use the alternate constructorBufferedReader(java.io.Reader in, int size)which accepts an input buffer size.)/* * Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 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 (args.length > 0 && args[0].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(); } } }$ java GrowBufferedReader grow Using new backing array, size=16384 $ java GrowBufferedReader Using original backing array, size=8192Note that the above example makes use of the array utility method
java.util.Arrays.copyOf).java.util.Arrayscontains many methods which are convenient when operating on arrays.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
example illustrates how to create and initialize a multi-dimensional array using reflection.CreateMatrix/* * Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 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]); } }$ java CreateMatrix matrix[0][0] = 1 matrix[0][1] = 2 matrix[1][0] = 3 matrix[1][1] = 4The same result could be obtained by using the following code fragment:
Object matrix = Array.newInstance(int.class, 2); Object row0 = Array.newInstance(int.class, 2); Object row1 = Array.newInstance(int.class, 2); Array.setInt(row0, 0, 1); Array.setInt(row0, 1, 2); Array.setInt(row1, 0, 3); Array.setInt(row1, 1, 4); Array.set(matrix, 0, row0); Array.set(matrix, 1, row1);The variable argument
Array.newInstance(Class<?> componentType, int... dimensions)provides a convenient way to create multi-dimensional arrays, but the components still need to initialized using the principle that that multi-dimensional arrays are nested arrays. (Reflection does not provide multiple indexedget/setmethods for this purpose.)