В информатике отражение - это способность процесс для изучения, самоанализа и изменения его собственной структуры и поведения.
Самые ранние компьютеры были запрограммированы на их родном языке ассемблера, который по своей природе был рефлексивным, поскольку эти оригинальные архитектуры можно было программировать, определяя инструкции как данные и используя самомодифицирующийся код. Поскольку программирование перешло на компилируемые языки более высокого уровня, такие как Algol, Cobol и Fortran (но также Pascal и C и многие другие языки), эта рефлексивная способность в значительной степени исчезла, пока не появились языки программирования с отражением, встроенным в их системы типов.>языки программирования и понятие мета-циклического интерпретатора как компонента.
Reflection помогает программистам создавать универсальные программные библиотеки для отображения данных, обработки различных форматов данных, выполнения сериализации или десериализации данных для связи, а также объединения и разделения данных для контейнеров или пакетов связи.
Для эффективного использования отражения почти всегда требуется план: структура дизайна, описание кодировки, библиотека объектов, карта базы данных или отношения сущностей.
Отражение делает язык более подходящим для сетевого кода. Например, он помогает таким языкам, как Java, хорошо работать в сетях, предоставляя библиотеки для сериализации, объединения и изменения форматов данных. Языки без отражения (например, C ) должны использовать вспомогательные компиляторы, например для Абстрактная синтаксическая нотация, чтобы создать код для сериализации и объединения.
Отражение можно использовать для наблюдения и изменения выполнения программы во время выполнения. Программный компонент, ориентированный на отражение, может контролировать выполнение вложенного кода и может изменять себя в соответствии с желаемой целью, связанной с этим вложением. Обычно это достигается путем динамического присвоения программного кода во время выполнения.
В объектно-ориентированных языках программирования, таких как Java, отражение позволяет проверять классы, интерфейсы, поля и методы во время выполнения без знания имен интерфейсов, полей и методов во время компиляции. Он также позволяет создавать экземпляры новых объектов и вызывать методы.
Отражение часто используется как часть тестирования программного обеспечения, например, для создания / создания экземпляров фиктивных объектов.
во время выполнения. Отражение также является ключевой стратегией для метапрограммирования.
В некоторых объектно-ориентированных языках программирования, таких как C # и Java, отражение может использоваться для обхода правил доступа членов. Для свойств C # это может быть достигнуто путем записи непосредственно в (обычно невидимое) поле поддержки закрытого свойства. Также можно найти закрытые методы классов и типов и вызвать их вручную. Это работает как для внутренних файлов проекта, так и для внешних библиотек (.Net-сборки и Java-архивы).
Язык, поддерживающий отражение, предоставляет ряд функций, доступных во время выполнения, которые иначе было бы трудно реализовать на языке более низкого уровня. Некоторые из этих функций позволяют:
Эти функции могут быть реализованы по-разному. В MOO рефлексия является естественной частью повседневной идиомы программирования. Когда вызываются глаголы (методы), различные переменные, такие как verb (имя вызываемого глагола) и this (объект, на котором вызывается глагол), заполняются, чтобы дать контекст вызова. Безопасность обычно управляется программным доступом к стеку вызывающего объекта: поскольку callers () - это список методов, с помощью которых в конечном итоге был вызван текущий глагол, выполнение тестов на callers () [0] (команда, запущенная исходным пользователем) позволяет глагол, чтобы защитить себя от несанкционированного использования.
Скомпилированные языки полагаются на свою систему времени выполнения, чтобы предоставить информацию об исходном коде. Скомпилированный исполняемый файл Objective-C, например, записывает имена всех методов в блоке исполняемого файла, предоставляя таблицу для соответствия их базовым методам (или селекторам для этих методов), скомпилированным в программу.. В скомпилированном языке, поддерживающем создание функций во время выполнения, например Common Lisp, среда выполнения должна включать компилятор или интерпретатор.
Отражение может быть реализовано для языков, не имеющих встроенных средств отражения, с помощью системы преобразования программ для определения автоматических изменений исходного кода.
Следующие ниже фрагменты кода создают экземпляр foo
из класса Foo
и вызывают его метод PrintHello
. Для каждого языка программирования показаны нормальные и основанные на отражении последовательности вызовов.
Ниже приведен пример в C# :
// Без отражения Foo foo = new Foo (); foo.PrintHello (); // С отражением Object foo = Activator.CreateInstance ("complete.classpath.and.Foo"); MethodInfo method = foo.GetType (). GetMethod ("PrintHello"); method.Invoke (foo, null);
В этом примере Delphi предполагается, что класс TFooбыл объявлен в модуле с именем Unit1:
использует RTTI, Unit1; процедура WithoutReflection; var Foo: TFoo; begin Foo: = TFoo.Create; попробуйте Foo.Hello; наконец Foo.Free; конец; конец; процедура WithReflection; var RttiContext: TRttiContext; RttiType: TRttiInstanceType; Foo: TObject; begin RttiType: = RttiContext.FindType ('Unit1.TFoo') как TRttiInstanceType; Foo: = RttiType.GetMethod ('Создать'). Invoke (RttiType.MetaclassType,).AsObject; попробуйте RttiType.GetMethod ('Hello'). Invoke (Foo,); наконец Foo.Free; конец; конец;
Ниже приведен пример в eC :
// Без отражения Foo foo {}; foo.hello (); // С классом отражения fooClass = eSystem_FindClass (__ thisModule, "Foo"); Экземпляр foo = eInstance_New (fooClass); Метод m = eClass_FindMethod (fooClass, "привет", fooClass.module); ((void (*) ()) (void *) m.function) (foo);
Ниже приведен пример в Go :
import "reflection" // Без отражения f: = Foo {} f.Hello () // С отражением fT: =lect.TypeOf (Foo {}) fV: = reflection.New (fT) m: = fV.MethodByName ("Hello") if m.IsValid () {m.Call (nil)}
Ниже приводится пример в Java :
import java.lang.reflect.Method; // Без отражения Foo foo = new Foo (); foo.hello (); // С отражением try {Object foo = Foo.class.newInstance (); Метод m = foo.getClass (). GetDeclaredMethod ("привет", новый класс >[0]); m.invoke (foo); } catch (ReflectiveOperationException игнорируется) {}
Ниже приведен пример в Objective-C, подразумевающий либо OpenStep, либо Используется структура Foundation Kit :
// Класс Foo. @interface Foo: NSObject - (void) привет; @end // Посылаем "привет" экземпляру Foo без отражения. Foo * obj = [[Foo alloc] init]; [obj привет]; // Отправляем "привет" экземпляру Foo с отражением. id obj = [[NSClassFromString (@ "Foo") alloc] init]; [obj performSelector: @selector (привет)];
Ниже приведен пример на Perl :
# Без отражения my $ foo = Foo->new; $ foo->привет; # или Foo->new->hello; # С отражением my $ class = "Foo" my $ constructor = "new"; мой $ method = "привет"; мой $ f = $ class ->$ constructor; $ f ->$ метод; # или $ class ->$ constructor ->$ method; # с eval eval "new Foo->hello;";
Ниже приведен пример в PHP :
// Без отражения $ foo = new Foo (); $ foo->привет (); // С отражением, используя Reflections API $ отражатель = new ReflectionClass ('Foo'); $ foo = $ отражатель->newInstance (); $ hello = $ отражатель->getMethod ('привет'); $ hello->invoke ($ foo);
Ниже приведен пример на Python :
# Без отражения obj = Foo () obj.hello () # С отражением obj = globals () ["Foo"] () getattr (obj, "hello") () # С eval eval ("Foo (). hello ()")
Ниже приведен пример в R :
# Без отражения, предполагая, что foo () возвращает S3- объект типа, имеющий метод "hello" obj <- foo() hello(obj) # With reflection the.class <- "foo" the.method <- "hello" obj <- do.call(the.class, list()) do.call(the.method, alist(obj))
Ниже приведен пример на Ruby :
# Без отражения obj = Foo.new obj.hello # С отражением class_name = "Foo "method_name =: hello obj = Object.const_get (class_name).new obj.send method_name # With eval" Foo.new.hello "
Ниже приведен пример использования Xojo :
'Без отражения Dim fooInstance As New Foo fooInstance.PrintHello' С отражением Dim classInfo As Introspection.Typeinfo = GetTypeInfo (Foo) Dim constructors () As Introspection.ConstructorInfo = classInfo.GetConstructors Dim fooInstance (0 constructors) Вызов методов Dim () как Introspection.MethodInfo = classInfo. GetMethods For Each m As Introspection.MethodInfo In методы If m.Name = "PrintHello" Then m.Invoke (fooInstance) End If Next