|
Spec-Zone .ru
спецификации, руководства, описания, API
|
Так же, как в неотражающем коде, поле массива может быть установлено или получено полностью или компонент компонентом. Чтобы установить весь массив сразу, использовать java.lang.reflect.Field.set(Object obj, Object value). Чтобы получить весь массив, использовать . Отдельные компоненты могут быть установлены или получали методы использования в .
обеспечивает методы формы setFoo() и getFoo() для установки и получения компонентов любого типа примитива. Например, компонент int массив может быть установлен с и может быть получен с .
Эти методы поддерживают автоматическое расширение типов данных. Поэтому, может использоваться, чтобы установить значения int массив начиная с 16-разрядного short может быть расширен до 32-разрядного int без потери данных; с другой стороны, вызов на массиве int вызовет быть брошенным потому что 64-разрядное long не может быть сужен к для хранения в 32-разрядном int с потерей информации. Это - истина независимо от того, могли ли бы фактические значения, которые передают, быть точно представлены в целевом типе данных. , разделы и , содержит полное обсуждение расширения и сужения преобразований.
Компоненты массивов ссылочных типов (включая массивы массивов) устанавливаются и получали использование и .
с большим. (Это предполагает что создание оригинала BufferedReader находится в коде, который не является поддающимся изменению; иначе, это было бы тривиально, чтобы просто использовать альтернативного конструктора который принимает входной размер буфера.)
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
Отметьте, что вышеупомянутый пример использует метод утилиты массива . содержит много методов, которые удобны, работая на массивах.
Многомерные массивы просто вкладываются массивы. Двумерный массив является массивом массивов. Трехмерный массив является массивом двумерных массивов и так далее.
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 методы с этой целью.)