Что такое рефлексия и почему она полезна?

в смешном совпадении, потому что сегодня в понедельник, он пропускает одно понедельное значение, поэтому они выглядят не по порядку. вчера это сработало бы хорошо.

i.e. ваш «+ 0 понедельник» - СЛЕДУЮЩИЙ понедельник, а не сегодня.

вы можете захотеть просмотреть символ формата «N» для даты ().

1936
задан laike9m 28 October 2015 в 06:30
поделиться

6 ответов

Отражение имени используется для описания кода, который в состоянии осмотреть другой код в той же системе (или оно).

, Например, скажите, что у Вас есть объект неизвестного типа в Java, и требуется назвать 'doSomething' метод на нем, если Вы существуете. Система статического контроля типов Java действительно не разработана для поддержки этого, если объект не соответствует известному интерфейсу, но отражение использования, код может посмотреть на объект и узнать, имеет ли это метод, названный 'doSomething', и затем назовите его, если Вы хотите.

Так, чтобы дать Вам пример кода этого в Java (воображают рассматриваемый объект, является нечто):

Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);

Один случай очень общего использования в Java является использованием с аннотациями. JUnit 4, например, будет использовать отражение для просмотра классов для методов, отмеченных с @Test аннотацией, и тогда назовет их при выполнении модульного теста.

существуют некоторые хорошие отражательные примеры для запущения Вас в http://docs.oracle.com/javase/tutorial/reflect/index.html

И наконец, да, понятия в значительной степени подобны в другом статически языки типов, которые поддерживают отражение (как C#). На динамически типизированных языках вариант использования, описанный выше, менее необходим (так как компилятор позволит любому методу быть названным на любом объекте, переставшем работать во времени выполнения, если это не будет существовать), но второй случай поиска методов, которые отмечены или работают определенным способом, все еще распространено.

Обновление из комментария:

способность осмотреть код в системе и видеть типы объектов не является отражением, а скорее Самоанализом Типа. Отражение является тогда способностью сделать модификации во времени выполнения путем использования самоанализа. Различие необходимо здесь, поскольку некоторые языки поддерживают самоанализ, но не поддерживают отражение. Одним таким примером является C++

1603
ответ дан Jishnu Prathap 28 October 2015 в 06:30
поделиться

Отражение является рядом функций, который позволяет Вам получать доступ к информации о выполнении своей программы и изменять его поведение (с некоторыми ограничениями).

Это полезно, потому что это позволяет Вам изменять время выполнения behaivour в зависимости от метаинформации Вашей программы, то есть, можно проверить тип возврата функции и изменить способ, которым Вы обрабатываете ситуацию.

В C#, например, можно загрузить блок (.dll) во времени выполнения исследование его, перейдя через классы и приняв меры согласно тому, что Вы нашли. Это также позволило Вам создать экземпляр класса на времени выполнения, вызвать его метод, и т.д.

, Где это может быть полезно? Не полезно каждый раз, но для конкретных ситуаций. Например, можно использовать его, чтобы получить название класса для входа целей, динамично создать обработчики для событий согласно тому, что определяется на конфигурационном файле и так далее...

14
ответ дан Jorge Córdoba 28 October 2015 в 06:30
поделиться

Не каждый язык поддерживает отражение, но принципы обычно являются тем же на языках, которые поддерживают его.

Отражение является способностью "отразиться" над структурой Вашей программы. Или более конкретный. Для рассмотрения объектов и классов, Вы имеете и программно возвращаете информацию о методах, полях и интерфейсах, которые они реализуют. Можно также посмотреть на вещи как аннотации.

Это полезно в большом количестве ситуаций. Везде Вы хотите быть в состоянии динамично включить классы в свой код. Партия объектных реляционных картопостроителей использует отражение, чтобы быть в состоянии инстанцировать объектов от баз данных, не зная заранее, что возражает, что они собираются использовать. Сменная архитектура является другим местом, где отражение полезно. Способность динамично загрузить код и определить, существуют ли типы там, которые реализуют правильный интерфейс для использования в качестве плагина, важна в тех ситуациях.

35
ответ дан Mendelt 28 October 2015 в 06:30
поделиться

Отражение является ключевым механизмом, чтобы позволить приложению или платформе работать с кодом, который еще, возможно, не был даже записан!

Берут, например, Ваш типичный файл web.xml. Это будет содержать список элементов сервлета, которые содержат вложенные элементы класса сервлета. Контейнер сервлета обработает файл web.xml и создаст новый новый экземпляр каждого класса сервлета посредством отражения.

Другим примером был бы API Java для XML Парсинг (JAXP) . Где поставщик синтаксического анализатора XML 'включается - в' через известные системные свойства, которые используются для построения новых экземпляров посредством отражения.

И наконец, самый всесторонний пример Spring, который использует отражение для создания его бобов, и для его интенсивного использования прокси

40
ответ дан toolkit 28 October 2015 в 06:30
поделиться

Одно из моего любимого использования отражения ниже метода дампа Java. Это берет любой объект в качестве параметра и использует API Reflection Java для распечатывания каждого имени поля и значения.

import java.lang.reflect.Array;
import java.lang.reflect.Field;

public static String dump(Object o, int callCount) {
    callCount++;
    StringBuffer tabs = new StringBuffer();
    for (int k = 0; k < callCount; k++) {
        tabs.append("\t");
    }
    StringBuffer buffer = new StringBuffer();
    Class oClass = o.getClass();
    if (oClass.isArray()) {
        buffer.append("\n");
        buffer.append(tabs.toString());
        buffer.append("[");
        for (int i = 0; i < Array.getLength(o); i++) {
            if (i < 0)
                buffer.append(",");
            Object value = Array.get(o, i);
            if (value.getClass().isPrimitive() ||
                    value.getClass() == java.lang.Long.class ||
                    value.getClass() == java.lang.String.class ||
                    value.getClass() == java.lang.Integer.class ||
                    value.getClass() == java.lang.Boolean.class
                    ) {
                buffer.append(value);
            } else {
                buffer.append(dump(value, callCount));
            }
        }
        buffer.append(tabs.toString());
        buffer.append("]\n");
    } else {
        buffer.append("\n");
        buffer.append(tabs.toString());
        buffer.append("{\n");
        while (oClass != null) {
            Field[] fields = oClass.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                buffer.append(tabs.toString());
                fields[i].setAccessible(true);
                buffer.append(fields[i].getName());
                buffer.append("=");
                try {
                    Object value = fields[i].get(o);
                    if (value != null) {
                        if (value.getClass().isPrimitive() ||
                                value.getClass() == java.lang.Long.class ||
                                value.getClass() == java.lang.String.class ||
                                value.getClass() == java.lang.Integer.class ||
                                value.getClass() == java.lang.Boolean.class
                                ) {
                            buffer.append(value);
                        } else {
                            buffer.append(dump(value, callCount));
                        }
                    }
                } catch (IllegalAccessException e) {
                    buffer.append(e.getMessage());
                }
                buffer.append("\n");
            }
            oClass = oClass.getSuperclass();
        }
        buffer.append(tabs.toString());
        buffer.append("}\n");
    }
    return buffer.toString();
}
103
ответ дан bwegs 28 October 2015 в 06:30
поделиться

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

, Например, все объекты в Java имеют метод getClass(), который позволяет Вам определить класс объекта, даже если Вы не знаете это во время компиляции (например, если бы Вы объявили его как Object) то - это могло бы казаться тривиальным, но такое отражение не возможно на менее динамических языках такой как C++. Более усовершенствованное использование позволяет Вам перечислить и назвать методы, конструкторов, и т.д.

, Отражение важно, так как оно позволяет Вам записать программы, которые не должны "знать" все во время компиляции, делая их более динамичными, так как они могут быть связаны во времени выполнения. Код может быть записан против известных интерфейсов, но фактические классы, которые будут использоваться, можно инстанцировать с помощью отражения от конфигурационных файлов.

Партии современных платформ используют отражение экстенсивно по этой самой причине. Большинство других современных языков использует отражение также, и в языках сценариев (таких как Python) они еще более тесно интегрируются, так как это чувствует себя более естественным в общей модели программирования тех языков.

224
ответ дан Sheharyar 28 October 2015 в 06:30
поделиться
Другие вопросы по тегам:

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