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

редактировать

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

Содержание

  • 1 Историческая справка
  • 2 Использование
  • 3 Реализация
  • 4 Примеры
    • 4.1 C #
    • 4.2 Delphi
    • 4.3 eC
    • 4.4 Go
    • 4.5 Java
    • 4.6 Objective-C
    • 4.7 Perl
    • 4.8 PHP
    • 4.9 Python
    • 4.10 R
    • 4.11 Ruby
    • 4.12 Xojo
  • 5 См. Также
  • 6 Ссылки
    • 6.1 Цитаты
    • 6.2 Источники
  • 7 Дополнительная литература
  • 8 Внешние ссылки

Историческая справка

Самые ранние компьютеры были запрограммированы на их родном языке ассемблера, который по своей природе был рефлексивным, поскольку эти оригинальные архитектуры можно было программировать, определяя инструкции как данные и используя самомодифицирующийся код. Поскольку программирование перешло на компилируемые языки более высокого уровня, такие как 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 #

Ниже приведен пример в 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

В этом примере 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

Ниже приведен пример в 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

Ниже приведен пример в 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

Ниже приводится пример в 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

Ниже приведен пример в 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

Ниже приведен пример на 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

Ниже приведен пример в PHP :

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

Python

Ниже приведен пример на Python :

# Без отражения obj = Foo () obj.hello () # С отражением obj = globals () ["Foo"] () getattr (obj, "hello") () # С eval eval ("Foo (). hello ()")

R

Ниже приведен пример в 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

Ниже приведен пример на 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

Ниже приведен пример использования 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

См. Также

Ссылки

Цитаты

Источники

Дополнительная литература

  • Ира Р. Форман и Нейт Форман, Java Reflection in Action (2005), ISBN 1-932394-18-4
  • Ира Р. Форман и Скотт Данфорт, Использование метаклассов (1999), ISBN 0-201-43305-2

Внешние ссылки

Последняя правка сделана 2021-06-03 11:26:45
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте