Из Википедии, бесплатной энциклопедии
  (Перенаправлено с Reflection (информатика) )
Перейти к навигации Перейти к поиску

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

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

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

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

Использует [ редактировать ]

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 (); фу . PrintHello ();// С отражением Object  foo  =  Activator . CreateInstance ( "complete.classpath.and.Foo" ); MethodInfo  method  =  foo . GetType (). GetMethod ( "PrintHello" ); метод . Invoke ( foo ,  null );

Delphi [ править ]

В этом примере Delphi предполагается, что класс TFoo объявлен в модуле с именем Unit1 :

использует  RTTI ,  Unit1 ;процедура  WithoutReflection ; var  Foo :  TFoo ; начало  Foo  : =  TFoo . Создать ;  попробуйте  Foo . Привет ;  наконец  Фу . Бесплатно ;  конец ; конец ;процедура  WithReflection ; var  RttiContext :  TRttiContext ;  RttiType :  TRttiInstanceType ;  Foo :  TObject ; begin  RttiType  : =  RttiContext . FindType ( 'Unit1.TFoo' )  как  TRttiInstanceType ;  Foo  : =  RttiType . GetMethod ( 'Создать' ) . Invoke ( RttiType . MetaclassType ,  []) . AsObject ; попробуйте  RttiType . GetMethod ( 'Привет' ) . Invoke ( Foo ,  []) ;  наконец  Фу . Бесплатно ;  конец ; конец ;

eC [ править ]

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

// Без отражения Foo  foo  {  }; фу . привет ();// С классом  отражения fooClass  =  eSystem_FindClass ( __thisModule ,  "Foo" ); Экземпляр  foo  =  eInstance_New ( fooClass ); Метод  m  =  eClass_FindMethod ( fooClass ,  "привет" ,  fooClass . Модуль ); (( void  ( * ) ()) ( void  * ) m . function ) ( foo );

Перейти [ править ]

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

импорт  "отразить"// Без отражения f  : =  Foo {} f . Привет ()// С отражением fT  : =  отражать . TypeOf ( Foo {}) fV  : =  отражать . Новый ( fT )m  : =  fV . MethodByName ( "Привет" ), если  m . IsValid ()  {  м . Call ( nil ) }

Java [ править ]

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

import  java.lang.reflect.Method ;// Без отражения Foo  foo  =  new  Foo (); фу . привет ();// С отражением пробуем  {  Object  foo  =  Foo . класс . newInstance (); Метод  m  =  foo . getClass (). getDeclaredMethod ( "привет" ,  новый  класс <?> [ 0 ] );  м . invoke ( foo ); }  catch  ( исключение ReflectiveOperationException  игнорируется )  {}

JavaScript [ править ]

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

// Без отражения const  foo  =  new  Foo () foo . привет ()// С отражением const  foo  =  Reflect . construct ( Foo ) const  hello  =  Отражать . get ( foo ,  'hello' ) Отражать . применить ( привет ,  foo ,  [])// С eval eval ( 'new Foo (). Hello ()' )

Юлия [ править ]

Ниже приведен пример на Julia (язык программирования) :

julia >  struct  Point  x :: Int  y  конец# Inspection с отражением Юли >  имен полей ( Точка ) ( : х ,  : у )julia >  fieldtypes ( Point ) ( Int64 ,  Любой )Юлия >  p  =  Point ( 3 , 4 )# Доступ с отражением джулия >  GetField ( р ,  : х ) 3

Objective-C [ править ]

Ниже приведен пример в Objective-C , подразумевающий, что используется среда OpenStep или Foundation Kit :

// Класс Foo. @interface  Foo  : NSObject -  ( void ) привет ; @конец// Отправляем "привет" экземпляру 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 . привет ()# С отражением obj  =  globals () [ "Foo" ] () getattr ( obj ,  "hello" ) ()# С eval eval ( "Foo (). Hello ()" )

R [ править ]

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

# Без отражения, предполагая, что foo () возвращает объект типа S3, который имеет метод "hello" obj  <-  foo () hello ( obj )# С отражением the.class  <-  "foo" the.method  <-  "hello" obj  <-  do.call ( the.class ,  list ()) do.call ( the.method ,  alist ( obj ))

Руби [ править ]

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

# Без отражения obj  =  Foo . новый OBJ . Привет# С отражением class_name  =  "Foo" method_name  =  : hello obj  =  Object . const_get ( имя_класс ) . новый OBJ . отправить  имя_метода# С eval eval  "Foo.new.hello"

Xojo [ править ]

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

'Без отражения Dim  fooInstance  As  New  Foo fooInstance . РаспечататьПривет'С отражением Dim  classInfo  As  Introspection . TypeInfo  =  GetTypeInfo ( Foo ) Dim  конструкторы ()  Как  самоанализ . ConstructorInfo  =  classInfo . GetConstructors Dim  fooInstance  As  Foo  =  constructors ( 0 ). Вызов методов Dim  () как самоанализ . MethodInfo = classInfo . GetMethods для каждого      м  как  самоанализ . MethodInfo  В  методах  Если  m . Name  =  "PrintHello"  Тогда  м . Вызов ( fooInstance )  End  If Next

См. Также [ править ]

  • Список языков и платформ рефлексивного программирования
  • Зеркало (программирование)
  • Парадигмы программирования
  • Самостоятельный хостинг
  • Самомодифицирующийся код
  • Типа самоанализ
  • тип

Ссылки [ править ]

Цитаты [ править ]

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

Источники [ править ]

  • Джонатан М. Собел и Дэниел П. Фридман. Введение в программирование, ориентированное на отражение (1996), Университет Индианы .
  • Техника Anti-Reflection с использованием оболочки C # и C ++ / CLI для предотвращения вора кода

Дальнейшее чтение [ править ]

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

Внешние ссылки [ править ]

  • Рефлексия в логике, функциональном и объектно-ориентированном программировании: краткое сравнительное исследование
  • Введение в программирование, ориентированное на отражение
  • Страницы Брайана Фута об отражении в Smalltalk
  • Учебное пособие по Java Reflection API от Oracle