Отражение (компьютерное программирование) - Reflection (computer programming)

В Информатика, программирование отражения это способность процесс исследовать, самоанализ, и изменить его собственную структуру и поведение.[1]

Историческое прошлое

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

Брайан Кантуэлл Смит докторская диссертация 1982 г.[2][3] ввел понятие вычислительного отражения в процедурных языки программирования и понятие мета-круговой интерпретатор как компонент 3-Лисп.

Использует

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

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

Отражение делает язык более подходящим для сетевого кода. Например, он помогает таким языкам, как Java, хорошо работать в сетях, предоставляя библиотеки для сериализации, объединения и изменения форматов данных. Языки без рефлексии (например, C ) должны использовать вспомогательные компиляторы, например за Нотация абстрактного синтаксиса, чтобы создать код для сериализации и объединения.

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

В объектно-ориентированных языках программирования, таких как Ява, отражение позволяет осмотр классов, интерфейсов, полей и методов во время выполнения, не зная имен интерфейсов, полей, методов во время компиляции. Это также позволяет реализация новых объектов и призыв методов.

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

Отражение также является ключевой стратегией для метапрограммирование.

В некоторых объектно-ориентированных языках программирования, например C # и Ява, отражение можно использовать для обхода доступность членов правила. Для свойств C # это может быть достигнуто путем записи непосредственно в (обычно невидимое) поле поддержки закрытого свойства. Также можно найти закрытые методы классов и типов и вызвать их вручную. Это работает как для внутренних файлов проекта, так и для внешних библиотек (.Net-сборки и Java-архивы).

Выполнение

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

  • Обнаруживать и изменять конструкции исходного кода (например, блоки кода, классы, методы, протоколы и т. д.) как первоклассные объекты во время выполнения.
  • Преобразовать нить соответствие символического имени класса или функции ссылке или вызову этого класса или функции.
  • Оцените строку, как если бы это был оператор исходного кода во время выполнения.
  • Создайте новый интерпретатор для байт-кода языка, чтобы придать новое значение или цель программной конструкции.

Эти функции могут быть реализованы по-разному. В MOO отражение является естественной частью идиомы повседневного программирования. Когда вызываются глаголы (методы), различные переменные, такие как глагол (название вызываемого глагола) и это (объект, на котором вызывается глагол) заполняются, чтобы дать контекст вызова. Безопасность обычно управляется программным доступом к стеку вызывающего объекта: звонящие() - это список методов, которыми в конечном итоге был вызван текущий глагол, выполняя тесты на звонящие() [0] (команда, запущенная исходным пользователем) позволяет глаголу защитить себя от несанкционированного использования.

Скомпилированные языки полагаются на свою систему времени выполнения, чтобы предоставить информацию об исходном коде. Скомпилированный Цель-C исполняемый файл, например, записывает имена всех методов в блоке исполняемого файла, предоставляя таблицу для их соответствия базовым методам (или селекторам для этих методов), скомпилированным в программу. На скомпилированном языке, который поддерживает создание функций во время выполнения, таких как Common Lisp, среда выполнения должна включать компилятор или интерпретатор.

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

Примеры

Следующие ниже фрагменты кода создают пример фу из учебный класс Фу и призываем его метод PrintHello. Для каждого язык программирования показаны нормальные и основанные на отражении последовательности вызовов.

C #

Ниже приводится пример в C #:

// Без отраженияФу фу = новый Фу();фу.PrintHello();// С отражениемОбъект фу = Активатор.CreateInstance("complete.classpath.and.Foo");MethodInfo метод = фу.GetType().GetMethod("PrintHello");метод.Вызвать(фу, ноль);

Delphi

Этот Delphi пример предполагает, что TFoo класс был объявлен в модуле под названием Раздел 1:

использует RTTI, Раздел 1;процедура Без отражения;вар  Фу: TFoo;начинать  Фу := TFoo.Создавать;  пытаться    Фу.Привет;  наконец-то    Фу.Свободный;  конец;конец;процедура С отражением;вар  RttiContext: TRttiContext;  RttiType: TRttiInstanceType;  Фу: TObject;начинать  RttiType := RttiContext.FindType('Unit1.TFoo') в качестве TRttiInstanceType;  Фу := RttiType.GetMethod('Создавать').Вызвать(RttiType.MetaclassType, []).AsObject;  пытаться    RttiType.GetMethod('Привет').Вызвать(Фу, []);  наконец-то    Фу.Свободный;  конец;конец;

eC

Ниже приводится пример в eC:

// Без отраженияФу фу { };фу.Привет();// С отражениемУчебный класс fooClass = eSystem_FindClass(__thisModule, "Фу");Пример фу = eInstance_New(fooClass);Метод м = eClass_FindMethod(fooClass, "Привет", fooClass.модуль);((пустота (*)())(пустота *)м.функция)(фу);

Идти

Ниже приводится пример в Идти:

импорт "отражать"// Без отраженияж := Фу{}ж.Привет()// С отражениемfT := отражать.Тип(Фу{})fV := отражать.Новый(fT)м := fV.MethodByName("Привет")если м.Действует() {    м.Вызов(ноль)}

Ява

Ниже приводится пример в Ява:

импорт java.lang.reflect.Method;// Без отраженияФу фу = новый Фу();фу.Привет();// С отражениемпытаться {    Объект фу = Фу.учебный класс.newInstance();    Метод м = фу.getClass().getDeclaredMethod("Привет", новый Учебный класс<?>[0]);    м.вызывать(фу);} ловить (ReflectiveOperationException игнорируется) {}

Цель-C

Ниже приводится пример в Цель-C, подразумевая либо OpenStep или же Фондовый комплект фреймворк используется:

// Класс Foo.@интерфейс Фу : NSObject- (пустота)Привет;@конец// Отправляем "привет" экземпляру Foo без отражения.Фу *объект = [[Фу выделить] в этом];[объект Привет];// Отправляем "привет" экземпляру Foo с отражением.я бы объект = [[NSClassFromString(@ "Фу") выделить] в этом];[объект PerformSelector: @selector(Привет)];

Perl

Ниже приводится пример в Perl:

# Без размышлениймой $ foo = Фу->новый;$ foo->Привет;# или жеФу->новый->Привет;# С отражениеммой $ класс = "Фу"мой конструктор $ = "новый";мой $ метод = "Привет";мой $ f = $ класс->конструктор $;$ f->$ метод;# или же$ класс->конструктор $->$ метод;# с evalоценка "новый Foo-> привет;";

PHP

Ниже приводится пример в PHP:

// Без отражения$ foo = новый Фу();$ foo->Привет();// С отражением, используя Reflections API$ отражатель = новый ReflectionClass('Фу');$ foo = $ отражатель->newInstance();$ привет = $ отражатель->getMethod('Привет');$ привет->вызывать($ foo);

Python

Ниже приводится пример в Python:

# Без размышленийобъект = Фу()объект.Привет()# С отражениемобъект = глобалы()["Фу"]()getattr(объект, "Привет")()# С evalоценка("Фу (). Привет ()")

р

Ниже приводится пример в р:

# Без отражения, предполагая, что foo () возвращает объект типа S3, который имеет метод "hello"объект <- фу()Привет(объект)# С отражениемкласс <- "фу"метод <- "Привет"объект <- do.call(класс, список())do.call(метод, список(объект))

Рубин

Ниже приводится пример в Рубин:

# Без размышленийобъект = Фу.новыйобъект.Привет# С отражениемclass_name = "Фу"имя_метода = :Приветобъект = Объект.const_get(class_name).новыйобъект.Отправить имя_метода# С evalоценка "Foo.new.hello"

Xojo

Ниже приведен пример использования Xojo:

'Без размышленийТусклый fooInstance В качестве Новый ФуfooInstance.PrintHello'С отражениемТусклый classInfo В качестве Самоанализ.Typeinfo = GetTypeInfo(Фу)Тусклый конструкторы() В качестве Самоанализ.ConstructorInfo = classInfo.GetConstructorsТусклый fooInstance В качестве Фу = конструкторы(0).ВызватьТусклый методы() В качестве Самоанализ.MethodInfo = classInfo.GetMethodsЗа Каждый м В качестве Самоанализ.MethodInfo В методы  Если м.Имя = "PrintHello" потом    м.Вызвать(fooInstance)  Конец ЕслиСледующий

Смотрите также

Рекомендации

Цитаты

  1. ^ Учебное пособие по поведенческой рефлексии и ее реализации, написанное Жаком Маленфантом и др. (PDF), неизвестно, заархивировано из оригинал (PDF) 21 августа 2017 г., получено 23 июн 2019
  2. ^ Брайан Кантуэлл Смит, Процедурное отражение в языках программирования, Факультет электротехники и информатики Массачусетского технологического института, докторская диссертация, 1982.
  3. ^ Брайан С. Смит. Отражение и семантика в процедурном языке В архиве 2015-12-13 на Wayback Machine. Технический отчет MIT-LCS-TR-272, Массачусетский технологический институт, Кембридж, Массачусетс, январь 1982 г.

Источники

дальнейшее чтение

  • Ира Р. Форман и Нейт Форман, Отражение Java в действии (2005), ISBN  1-932394-18-4
  • Ира Р. Форман и Скотт Данфорт, Запуск метаклассов в работу (1999), ISBN  0-201-43305-2

внешняя ссылка