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

1812

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

Меня особенно интересует Java, но я предполагаю, что принципы одинаковы на любом языке.

  • 6
    Для меня это способ получения имен классов во время выполнения и создания объектов этого класса.
  • 39
    потому что это популярный вопрос, я хотел бы отметить, что рефлексия (без аннотаций) должна быть последним инструментом, к которому вы обращаетесь при решении проблемы. Я использую это и люблю это, но это устраняет все преимущества статической типизации Java. Если вам это нужно, выделите его как можно меньше (один метод или один класс). Более приемлемо использовать его в тестах, чем производственный код. С аннотациями все должно быть в порядке - главное не указывать имена классов или методов как «Strings», если вы можете избежать этого.
Показать ещё 3 комментария
Теги:
reflection
terminology

21 ответ

1500
Лучший ответ

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

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

Итак, чтобы дать вам пример кода этого в Java (предположим, что объект, о котором идет речь, является foo):

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

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

Есть несколько хороших примеров отражения, которые помогут вам начать работу по адресу http://docs.oracle.com/javase/tutorial/reflect/index.html.

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

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

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

  • 29
    Можете ли вы объяснить, каково значение этого нулевого параметра в этой строке Method method = foo.getClass (). getMethod ("doSomething", null);
  • 50
    Нулевое значение указывает, что в метод foo не переданы параметры. См. Docs.oracle.com/javase/6/docs/api/java/lang/reflect/… , java.lang.Object ...) для подробностей.
Показать ещё 10 комментариев
217

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

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

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

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

  • 2
    Другими словами, вы можете создать экземпляр из его квалифицированного имени, и компилятор не будет жаловаться на это (потому что, скажем, вы используете просто String для имени класса). Затем, во время выполнения, если этот класс отсутствует, вы получите исключение. Вы вроде обошли компилятор в этом случае. Не могли бы вы дать мне конкретный вариант использования для этого? Я просто не могу представить, когда выберу это.
  • 3
    @FernandoGabrieli, хотя верно, что с помощью отражения легко создавать ошибки времени выполнения, также вполне возможно использовать отражение, не рискуя исключениями времени выполнения. Как указывалось в моем ответе, обычное использование рефлексии - для библиотек или структур, которые явно не могут знать структуру приложения во время компиляции, поскольку они компилируются отдельно от приложения. Любая библиотека, которая использует «код по соглашению», вероятно, будет использовать отражение, но не обязательно использовать магические строки.
93

Одно из моих любимых отражений - метод дампа ниже. Он принимает любой объект в качестве параметра и использует API отражения 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();
}
  • 7
    На что должен быть установлен Callcount?
  • 6
    Я получил исключение в потоке "AWT-EventQueue-0" java.lang.StackOverflowError, когда я запустил это.
Показать ещё 3 комментария
64

Использование отражений

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

Возможности расширения

Приложение может использовать внешние пользовательские классы, создавая экземпляры объектов расширяемости, используя их полностью квалифицированные имена. Браузеры классов и среды визуального развития Браузер классов должен иметь возможность перечислять члены классов. Визуальные среды разработки могут извлечь выгоду из использования информации типа, доступной для размышления, чтобы помочь разработчику в написании правильного кода. Отладчики и средства тестирования Отладчики должны иметь возможность проверять частных членов в классах. Тестовые жгуты могут использовать рефлексию для систематического вызова установленных API-интерфейсов обнаружения, определенных в классе, для обеспечения высокого уровня охвата кода в наборе тестов.

Недостатки отражения

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

  • Производительность

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

  • Ограничения безопасности

Для отражения требуется разрешение во время выполнения, которое может отсутствовать при работе под управлением безопасности. Это важно для кода, который должен выполняться в ограниченном контексте безопасности, например, в Applet.

  • Воздействие внутренних

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

источник: API Reflection

36

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

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

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

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

32

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

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

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

  • 0
    Мне нужно создавать экземпляры объектов на основе данных, представленных в БД. Я считаю, что это то, о чем вы говорите. Пример кода очень мне поможет. Заранее спасибо.
30

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

Class myObjectClass = MyObject.class;
Method[] method = myObjectClass.getMethods();

//Here the method takes a string parameter if there is no param, put null.
Method method = aClass.getMethod("method_name", String.class); 

Object returnValue = method.invoke(null, "parameter-value1");

В приведенном выше примере нулевой параметр - это объект, на который вы хотите вызвать метод. Если метод статичен, вы отправляете нуль. Если метод не является статичным, то при вызове вам нужно указать действительный экземпляр MyObject вместо null.

Reflection также позволяет вам получить доступ к частному члену/методам класса:

public class A{

  private String str= null;

  public A(String str) {
  this.str= str;
  }
}

.

A obj= new A("Some value");

Field privateStringField = A.class.getDeclaredField("privateString");

//Turn off access check for this field
privateStringField.setAccessible(true);

String fieldValue = (String) privateStringField.get(obj);
System.out.println("fieldValue = " + fieldValue);
  • Для проверки классов (также известных как интроспекция) вам не нужно импортировать пакет отражения (java.lang.reflect). Доступ к метаданным класса возможен через java.lang.Class.

Reflection - очень мощный API, но он может замедлить работу приложения, если он используется в избытке, поскольку он разрешает все типы во время выполнения.

  • 1
    Это пост, который помог мне больше всего в разделе ответов спасибо, Нихил
19

Java Reflection довольно мощный и может быть очень полезным. Java Reflection позволяет проверять классы, интерфейсы, поля и методы во время выполнения,, не зная имена классов, методов и т.д. Во время компиляции. Также возможно создавать новые объекты, вызывать методы и получать/устанавливать значения полей с помощью отражения.

Быстрый пример Java Reflection, чтобы показать вам, что использует отражение:

Method[] methods = MyObject.class.getMethods();

    for(Method method : methods){
        System.out.println("method = " + method.getName());
    }

В этом примере получен объект класса из класса MyObject. Используя объект класса, пример получает список методов в этом классе, выполняет итерации методов и распечатывает их имена.

Именно здесь объясняется, как все это работает

Изменить. Почти через год я редактирую этот ответ, когда читаю об отражении. Я получил еще несколько применений Reflection.

  • Spring использует конфигурацию bean, такую ​​как:


<bean id="someID" class="com.example.Foo">
    <property name="someField" value="someValue" />
</bean>

Когда контекст Spring обрабатывает этот <bean> , он будет использовать Class.forName(String) с аргументом "com.example.Foo" для создания экземпляра этого класса.

Затем он снова использует отражение, чтобы получить соответствующий сеттер для <property> и установите его значение в указанное значение.

  • Junit использует Reflection специально для тестирования частных/защищенных методов.

Для частных методов

Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

Для частных полей

Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
19

Пример:
Возьмите, например, удаленное приложение, которое дает вашему приложению объект, который вы получаете, используя их методы API. Теперь, основываясь на объекте, вам может понадобиться выполнить какое-то вычисление.
Поставщик гарантирует, что объект может иметь 3 типа, и нам нужно выполнить вычисления на основе того, какой тип объекта.
Таким образом, мы можем реализовать в 3 классах, каждый из которых содержит другую логику. Очевидно, информация об объекте доступна во время выполнения, поэтому вы не можете статически кодировать для выполнения вычислений, поэтому отражение используется для создания объекта класса, который требуется выполнить вычисление на основе объекта, полученного от поставщика.

  • 0
    Мне нужно что-то подобное .. Пример очень мне поможет, так как я новичок в рефлексии концепций ..
  • 0
    Я запутался: нельзя ли использовать instanceof для определения типа объекта во время выполнения?
14

Отражение - это API, который используется для изучения или изменения поведения методов, классов, интерфейсов во время выполнения.

  • Необходимые классы для отражения предоставляются под java.lang.reflect package.
  • Reflection дает нам информацию о классе, к которому принадлежит объект, а также о методах этого класса, которые могут быть выполнены с использованием объекта.
  • Через отражение мы можем ссылаться на методы во время выполнения, независимо от используемого с ними спецификатора доступа.

Пакеты java.lang и java.lang.reflect предоставляют классы для отражения java.

Отражение можно использовать для получения информации о -

  • Класс Метод getClass() используется для получения имени класса, к которому принадлежит объект.

  • Конструкторы Метод getConstructors() используется для получения общих конструкторов класса, к которому принадлежит объект.

  • Методы Метод getMethods() используется для получения общедоступных методов класса, к которому принадлежат объекты.

Reflection API используется в основном:

IDE (интегрированная среда разработки), например. Eclipse, MyEclipse, NetBeans и т.д.
Отладчик и тестовые инструменты и т.д.

Изображение 1317

Преимущества использования Reflection:

Возможности расширяемости: приложение может использовать внешние, определенные пользователем классы, создавая экземпляры объектов расширяемости, используя их полностью квалифицированные имена.

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

Недостатки:

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

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

Ссылка: Отражение Java javarevisited.blogspot.in p >

  • 4
    Я бы добавил к недостаткам " Это нарушает рефакторинг ". Для меня это главная причина, чтобы как можно больше избегать размышлений.
  • 0
    Таким образом, это позволяет нам (например) проверять классы, которые у нас есть (есть ли у нас их экземпляры или нет), правильно? Под этим я подразумеваю получение их методов или конструкторов и использование их для создания новых экземпляров / их вызова. Почему мы говорим «изменение поведения программы», если поведение уже есть, но с другим кодом? Почему это называется «отражение»? Спасибо
14

В соответствии с моим пониманием:

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

Он часто используется в сценариях, где имя класса часто меняется. Если такая ситуация возникает, то программисту сложно перезаписать приложение и изменить имя класса снова и снова.

Вместо этого, используя рефлексию, нужно беспокоиться о возможно изменяющемся имени класса.

13

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

public class Test {

    public void firstMoveChoice(){
        System.out.println("First Move");
    } 
    public void secondMOveChoice(){
        System.out.println("Second Move");
    }
    public void thirdMoveChoice(){
        System.out.println("Third Move");
    }

    public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { 
        Test test = new Test();
        Method[] method = test.getClass().getMethods();
        //firstMoveChoice
        method[0].invoke(test, null);
        //secondMoveChoice
        method[1].invoke(test, null);
        //thirdMoveChoice
        method[2].invoke(test, null);
    }

}
13

Reflection - это набор функций, который позволяет вам получать доступ к информации о времени выполнения вашей программы и изменять ее поведение (с некоторыми ограничениями).

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

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

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

10

Отражение - позволить объекту увидеть их внешний вид. Этот аргумент не имеет никакого отношения к размышлению. Фактически, это способность "идентифицировать себя".

Сама рефлексия - это слово для таких языков, которые не обладают способностью к самопознанию и самочувствию как Java и С#. Поскольку у них нет возможности самопознания, когда мы хотим наблюдать, как это выглядит, у нас должно быть другое дело, чтобы подумать о том, как это выглядит. Отличные динамические языки, такие как Ruby и Python, могут воспринимать свое отражение без помощи других людей. Можно сказать, что объект Java не может воспринимать, как это выглядит без зеркала, которое является объектом класса отражения, но объект в Python может воспринимать его без зеркала. Поэтому нам нужно размышлять на Java.

  • 0
    type (), isinstance (), callable (), dir () и getattr (). .... это призывы к питоническому отражению
8

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

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

8

На странице документации java

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

AccessibleObject позволяет подавлять проверки доступа, если имеется необходимый ReflectPermission.

Классы в этом пакете наряду с java.lang.Class включают приложения, такие как отладчики, интерпретаторы, инспекторы объектов, браузеры классов и сервисы, такие как Object Serialization и JavaBeans которым нужен доступ либо к публичным членам целевого объекта (на основе его runtime class) или членов, объявленных данным классом

Он включает следующие функции.

  1. Получение объектов класса,
  2. Изучение свойств класса (полей, методов, конструкторов),
  3. Установка и получение значений полей,
  4. Вызов методов,
  5. Создание новых экземпляров объектов.

Посмотрите ссылку на эту документацию для методов, открытых Class класса.

Из этой статьи (Деннис Сосноски, президент Sosnoski Software Solutions, Inc) и этой статьи (security-explorations pdf):

Я вижу значительные недостатки, чем использование использования Reflection

Пользователь отражения:

  1. Он обеспечивает очень универсальный способ динамической компоновки компонентов программы
  2. Он полезен для создания библиотек, которые работают с объектами очень широко

Недостатки отражения:

  1. Отражение происходит гораздо медленнее, чем прямой код при использовании для доступа к полям и методам.
  2. Это может скрыть то, что происходит внутри вашего кода.
  3. Он обходит исходный код, может создавать проблемы обслуживания
  4. Код отражения также более сложный, чем соответствующий прямой код
  5. Это позволяет нарушать ключевые ограничения безопасности Java, такие как защита доступа к данным и безопасность типов

Общие злоупотребления:

  1. Загрузка ограниченных классов,
  2. Получение ссылок на конструкторы, методы или поля ограниченного класса,
  3. Создание новых экземпляров объектов, вызов методов, получение или установка значений полей ограниченного класса.

Взгляните на этот вопрос SE относительно злоупотребления функцией отражения:

Как прочитать приватное поле в Java?

Резюме:

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

8

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

С Reflection API вы можете написать универсальный метод toString() для любого объекта.

Это полезно при отладке.

Вот пример:

class ObjectAnalyzer {

   private ArrayList<Object> visited = new ArrayList<Object>();

   /**
    * Converts an object to a string representation that lists all fields.
    * @param obj an object
    * @return a string with the object class name and all field names and
    * values
    */
   public String toString(Object obj) {
      if (obj == null) return "null";
      if (visited.contains(obj)) return "...";
      visited.add(obj);
      Class cl = obj.getClass();
      if (cl == String.class) return (String) obj;
      if (cl.isArray()) {
         String r = cl.getComponentType() + "[]{";
         for (int i = 0; i < Array.getLength(obj); i++) {
            if (i > 0) r += ",";
            Object val = Array.get(obj, i);
            if (cl.getComponentType().isPrimitive()) r += val;
            else r += toString(val);
         }
         return r + "}";
      }

      String r = cl.getName();
      // inspect the fields of this class and all superclasses
      do {
         r += "[";
         Field[] fields = cl.getDeclaredFields();
         AccessibleObject.setAccessible(fields, true);
         // get the names and values of all fields
         for (Field f : fields) {
            if (!Modifier.isStatic(f.getModifiers())) {
               if (!r.endsWith("[")) r += ",";
               r += f.getName() + "=";
               try {
                  Class t = f.getType();
                  Object val = f.get(obj);
                  if (t.isPrimitive()) r += val;
                  else r += toString(val);
               } catch (Exception e) {
                  e.printStackTrace();
               }
            }
         }
         r += "]";
         cl = cl.getSuperclass();
      } while (cl != null);

      return r;
   }    
}
5

Отражение дает вам возможность писать более общий код. Он позволяет создавать объект во время выполнения и вызывать его метод во время выполнения. Следовательно, программа может быть сильно параметризована. Он также позволяет исследовать объект и класс для обнаружения его переменных и метода, открытых во внешнем мире.

5

Reflection имеет много использует. Я больше знаком с тем, чтобы иметь возможность создавать код "на лету".

IE: динамические классы, функции, конструкторы - на основе любых данных (xml/array/sql results/hardcoded/etc..)

  • 1
    Этот ответ был бы намного лучше, если бы вы привели только один необычный пример сгенерированного кода из результата SQL, файла XML и т. Д.
  • 0
    Нет проблем. Я использовал отражение в приложении Windows, которое динамически генерирует интерфейс на основе XML, взятого из базы данных.
Показать ещё 1 комментарий
2

Я хочу ответить на этот вопрос на примере. Прежде всего, проект Hibernate использует Reflection API для генерации CRUD заявлений для преодоления пропасти между запущенным приложением и хранилищем персистентности. Когда что-то меняется в домене, Hibernate должен знать о них, чтобы они сохраняли их в хранилище данных и наоборот.

В качестве альтернативы работает Lombok Project. Он просто вводит код во время компиляции, приводит к введению кода в ваши классы домена. (Я думаю, что это нормально для геттеров и сеттеров)

Hibernate выбрал reflection поскольку оно оказывает минимальное влияние на процесс сборки приложения.

А из Java 7 мы имеем MethodHandles, который работает как Reflection API. В проектах, чтобы работать с регистраторами, мы просто копируем-вставляем следующий код:

Logger LOGGER = Logger.getLogger(MethodHandles.lookup().lookupClass().getName());

Потому что в этом случае сложно сделать typo-error.

-6

Java Reflection позволяет проверять классы, интерфейсы, поля и методы во время выполнения, не зная имена классов, методов и т.д. во время компиляции. В основном на уровне каркаса могут быть достигнуты максимальные выгоды от отражения. Байт-код, который компилируется, если для проверки требуется дополнительная модификация во время выполнения, модификация, добавление большего байтового кода в себя или другая программа или другая структура на уровне метода, уровень переменных экземпляра, уровень конструктора, отражение уровня аннотации.

Предположим, что у вас есть метод add(Int a,int b). Эквивалентный байтовый код предположим B1. Если вы предположили, что в вашей системе 1000 методов с именем add. Теперь вы хотите проверить значение параметра a и b до вызова метода add. Таким образом, вы можете приклеить свой код к другой программе или фреймворку, который использует отражение для динамического изучения значения байтового кода с помощью Object.getClass.getMethod(). Существует несколько классов для изучения. Он может добавить дополнительную операцию до вызова метода add. Но сама программа или другая программа или структура не знают об объекте, который имеет метод с именем add. В основном в зависимости от употребления в основном используется использование рефлексии с использованием аспектного ориентирования.

  • 16
    -1 отражение ничего не делает с манипуляциями, модификациями или генерацией байт-кода.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню