Какова цель java.lang.reflect. Методы получателя массива и методы установщика?

Класс Java java.lang.reflect. Массив обеспечивает ряд инструментов для создания массива динамично. Однако в дополнение к этому это имеет полный набор методов для доступа (получите, установите, и длина), массив. Я не понимаю точку этого, так как Вы можете (и по-видимому был бы) снимать Ваш динамично сгенерированный массив в качестве массива после создания, что означает, что можно использовать нормальный доступ к массиву (нотация скобки) функциональность. На самом деле смотря на исходный код Вы видите, что это - весь класс, делает, бросает массив и выдают исключение, если состав исполнителей перестал работать.

Так какой смысл / полноценность всех этих дополнительных методов?

Обновление

Весь примитив get*() и set*() методы кажутся особенно бесполезными, полагая, что необходимо знать тип массива заранее для знания который метод использовать.

Обновление 2

Спасибо все, Ваш вход был очень образовательным! Я не могу действительно видеть, когда я использовал бы этот класс для чего-либо кроме newInstance() (и возможно getLength()), но я теперь понимаю, что эти другие методы все еще довольно полезны.

6
задан dimo414 18 May 2015 в 16:15
поделиться

3 ответа

Этот класс довольно эзотеричен - большинство случаев использования массивов знают тип массива, поэтому этот класс обычно наиболее полезен при реализации кода, который работает с массивами обобщенно.

Не существует суперкласса массива для всех массивов, поэтому нет единого способа доступа к элементам или размеру массива независимо от типа. java.lang.reflect.Array заполняет этот пробел и позволяет обращаться к массиву одинаковым образом независимо от типа. Например, чтобы получить значение по заданному индексу из любого массива (возвращаемое как объект).

Это параметрический полиморфизм. Конечно, вы можете сделать это сами, если знаете тип - вы просто делаете кастинг. Если вы не знаете тип массива, или он может быть нескольких типов, вы должны проверить возможности и выполнить соответствующее приведение - что и делает код в reflect.Array.

EDIT: В ответ на комментарий. Подумайте, как бы вы решили эту проблему - как подсчитать, сколько раз значение дублируется в массиве. Без класса Array, диагностирующего типы, это было бы невозможно, без явного приведения массива, поэтому для каждого типа массива нужна своя функция. Здесь у нас есть одна функция, которая работает с любым типом массива.

public Map<Object, Integer> countDuplicates(Object anArray)
{
    if (!anArray.getClass().isArray())
        throw new IllegalArgumentException("anArray is not an array");

    Map<Object,Integer> dedup = new HashMap<Object,Integer>();
    int length = Array.getLength(anArray);
    for (int i=0; i<length; i++)
    {
        Object value = Array.get(anArray, i);         
        Integer count = dedup.get(value);
        dedup.put(value, count==null ? 1 : count+1);
    }
    return dedup;
}

EDIT2: Что касается методов get*() и set*(). Приведенная выше ссылка на исходный код указывает на гармонию Apache. Реализация там не соответствует Sun Javadocs. Например, из метода getInt

@throws IllegalArgumentException If the specified object is not an array, 
or if the indexed element cannot be converted to the return type 
by an identity or widening conversion 

Это подразумевает, что фактический массив может быть byte[], short[] или int[]. Это не относится к реализации Harmony, которая принимает только int[]. (Кстати, реализация Sun использует собственные методы для большей части класса Array). Методы get*() и set*() существуют по той же причине, что и get(), getLength() - для обеспечения (слабо) диагностируемого по типу доступа к массиву.

Это не совсем то, что вам нужно использовать каждый день, но я представляю, как это полезно для тех, кому это нужно.

8
ответ дан 9 December 2019 в 20:40
поделиться

Эти методы освобождают вас от необходимости самостоятельно проверять и приводить массив, если все, что вы знаете, это "этот объект является массивом некоторого (возможно, примитивного) типа".

Сам я видел применение этого только во фреймворках и утилитах, таких как commons-beanutils. Этот фреймворк рефлексивно обращается к свойствам java beans и использует методы Array для доступа к элементам свойств массива.

2
ответ дан 9 December 2019 в 20:40
поделиться

Что касается методов set ... () , они действительно полезны:

Object a = new byte[1], b = new short[1], c = new int[1], d = new long[1];
Array.setByte(a, 0, (byte)1);
Array.setByte(b, 0, (byte)1);
Array.setByte(c, 0, (byte)1);
Array.setByte(d, 0, (byte)1);

Вам не нужно знать, является ли массив, с которым вы имеете дело, int [ ] или long [] , например, для установки значения 5 .

Править Я изменил пример, чтобы продемонстрировать тот факт, что методы set ... () позволяют не обязательно знать тип примитивного массива статически.

2
ответ дан 9 December 2019 в 20:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: