Spec-Zone .ru
спецификации, руководства, описания, API
След: API Reflection
Урок: Массивы и Перечислимые типы
Раздел: Массивы
Получение и Установка Массивов и Их Компонентов
Домашняя страница > API Reflection > Массивы и Перечислимые типы

Получение и Установка Массивов и Их Компонентов

Так же, как в неотражающем коде, поле массива может быть установлено или получено полностью или компонент компонентом. Чтобы установить весь массив сразу, использовать 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 быть брошенным потому что 64-разрядное long не может быть сужен к для хранения в 32-разрядном int с потерей информации. Это - истина независимо от того, могли ли бы фактические значения, которые передают, быть точно представлены в целевом типе данных. Спецификация языка Java, Java SE 7 Выпусков, разделы, Расширяющие Примитивное Преобразование и Сужающие Примитивное Преобразование, содержит полное обсуждение расширения и сужения преобразований.

Компоненты массивов ссылочных типов (включая массивы массивов) устанавливаются и получали использование Array.set(Object array, int index, int value) и Array.get(Object array, int index).

Установка Поля Массива Типа

GrowBufferedReader пример иллюстрирует, как заменить значение поля массива типа. В этом случае код заменяет отступающий массив для a 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 методы с этой целью.)


Проблемы с примерами? Попытайтесь Компилировать и Выполнить Примеры: FAQ.
Жалобы? Поздравление? Предложения? Дайте нам свою обратную связь.

Предыдущая страница: Создание Новых Массивов
Следующая страница: Поиск и устранение неисправностей