Spec-Zone .ru
спецификации, руководства, описания, API
|
Так же, как в неотражающем коде, поле массива может быть установлено или получено полностью или компонент компонентом. Чтобы установить весь массив сразу, использовать java.lang.reflect.Field.set(Object obj, Object value)
. Чтобы получить весь массив, использовать Field.get(Object)
java.lang.reflect.Array
Array
setFoo()
и getFoo()
для установки и получения компонентов любого типа примитива. Например, компонент int
массив может быть установлен с Array.setInt(Object array, int index, int value)
Array.getInt(Object array, int index)
Эти методы поддерживают автоматическое расширение типов данных. Поэтому, Array.getShort()
int
массив начиная с 16-разрядного short
может быть расширен до 32-разрядного int
без потери данных; с другой стороны, вызов Array.setLong()
int
вызовет IllegalArgumentException
long
не может быть сужен к для хранения в 32-разрядном int
с потерей информации. Это - истина независимо от того, могли ли бы фактические значения, которые передают, быть точно представлены в целевом типе данных.
Компоненты массивов ссылочных типов (включая массивы массивов) устанавливаются и получали использование Array.set(Object array, int index, int value)
Array.get(Object array, int index)
пример иллюстрирует, как заменить значение поля массива типа. В этом случае код заменяет отступающий массив для a GrowBufferedReader
java.io.BufferedReader
BufferedReader
находится в коде, который не является поддающимся изменению; иначе, это было бы тривиально, чтобы просто использовать альтернативного конструктора BufferedReader(java.io.Reader in, int size)
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=8192
Отметьте, что вышеупомянутый пример использует метод утилиты массива java.util.Arrays.copyOf)
java.util.Arrays
Многомерные массивы просто вкладываются массивы. Двумерный массив является массивом массивов. Трехмерный массив является массивом двумерных массивов и так далее.
пример иллюстрирует, как создать и инициализировать многомерный массив, использующий отражение.CreateMatrix
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] = 4
Тот же самый результат мог быть получен при использовании следующего фрагмента кода:
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);
Переменный параметр Array.newInstance(Class<?> componentType, int... dimensions)
обеспечивает удобный способ создать многомерные массивы, но компоненты все еще нуждаются к инициализированному использованию принципа, что это многомерные массивы вкладывается массивы. (Отражение не обеспечивает многократный индексированный get
/set
методы с этой целью.)