~~~~~~~~~~~~~~~~~~~~ Arc.Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~ 
Номер скриншота №:
✰ 695E05B04F04BFD3F08CF167FC4DD5DE__1718394900 ✰
Заголовок документа оригинал.:
✰ Reflective programming - Wikipedia ✰
Заголовок документа перевод.:
✰ Рефлексивное программирование — Википедия ✰
Снимок документа находящегося по адресу (URL):
✰ https://en.wikipedia.org/wiki/Reflective_programming ✰
Адрес хранения снимка оригинал (URL):
✰ https://arc.ask3.ru/arc/aa/69/de/695e05b04f04bfd3f08cf167fc4dd5de.html ✰
Адрес хранения снимка перевод (URL):
✰ https://arc.ask3.ru/arc/aa/69/de/695e05b04f04bfd3f08cf167fc4dd5de__translat.html ✰
Дата и время сохранения документа:
✰ 16.06.2024 10:32:09 (GMT+3, MSK) ✰
Дата и время изменения документа (по данным источника):
✰ 14 June 2024, at 22:55 (UTC). ✰ 

~~~~~~~~~~~~~~~~~~~~~~ Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~~ 
Сервисы Ask3.ru: 
 Архив документов (Снимки документов, в формате HTML, PDF, PNG - подписанные ЭЦП, доказывающие существование документа в момент подписи. Перевод сохраненных документов на русский язык.)https://arc.ask3.ruОтветы на вопросы (Сервис ответов на вопросы, в основном, научной направленности)https://ask3.ru/answer2questionТоварный сопоставитель (Сервис сравнения и выбора товаров) ✰✰
✰ https://ask3.ru/product2collationПартнерыhttps://comrades.ask3.ru


Совет. Чтобы искать на странице, нажмите Ctrl+F или ⌘-F (для MacOS) и введите запрос в поле поиска.
Arc.Ask3.ru: далее начало оригинального документа

Рефлексивное программирование — Википедия Jump to content

Рефлексивное программирование

Из Википедии, бесплатной энциклопедии

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

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

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

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

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

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

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

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

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

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

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

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

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

Реализация [ править ]

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

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

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

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

Соображения безопасности [ править ]

Отражение может позволить пользователю создавать неожиданные пути потока управления через приложение, потенциально в обход мер безопасности. Этим могут воспользоваться злоумышленники. [4] Исторические уязвимости в Java, вызванные небезопасным отражением, позволяли коду, полученному с потенциально ненадежных удаленных компьютеров, выйти из изолированной программной среды механизма безопасности Java. Крупномасштабное исследование 120 уязвимостей Java, проведенное в 2013 году, пришло к выводу, что небезопасное отражение является наиболее распространенной уязвимостью в Java, хотя и не самой часто используемой. [5]

Примеры [ править ]

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

Общий Лисп [ править ]

пример Ниже приведен использования Common Lisp Object System :

(  defclass   foo   ()   ()) 
 (  defmethod   print-hello   ((  f   foo  ))   (  format   T   "Привет от ~S~%"   f  )) 

 ;;   Нормально, без отражения 
 (  let   ((  foo   (  make-instance   'foo  ))) 
   (  print-hello   foo  )) 

 ;;   С отражением для поиска класса с именем «foo» и метода 
 ;;   с именем «print-hello», специализирующимся на «foo». 
  (  let*   ((  foo-class   (  find-class   (  read-from-string   "foo"  ))) 
        (  print-hello-method   (  find-method   (  symbol-function   (  read-from-string   "print-hello"  ) ) 
                                         nil   (  список   foo-класса  )))) 
   (  funcall   (  sb-mop:method-generic-function   print-hello-method  ) 
            (  make-instance   foo-class  ))) 


С# [ править ]

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

// Без отражения 
 var   foo   =   new   Foo  (); 
  фу  .   РаспечататьПривет  (); 

  // С отражением 
 Object   foo   =   Activator  .   CreateInstance  (  "complete.classpath.and.Foo"  ); 
  MethodInfo   метод   =   foo  .   ПолучитьТип  ().   GetMethod  (  "PrintHello"  ); 
  метод  .   Вызвать  (  фу  ,   ноль  ); 

Delphi, Object Pascal [ править ]

В этом примере Delphi и Object Pascal предполагается, что Класс TFoo был объявлен в модуле под названием Раздел 1 :

использует   RTTI  ,   Unit1  ; 

  процедура   БезОтражения  ; 
  вар 
   Фу  :   TFoo  ; 
  начать 
   Фу   :=   TFoo  .   Создавать  ; 
    попробуй 
     Фу  .   Привет  ; 
    наконец 
     Фу  .   Бесплатно  ; 
    конец  ; 
  конец  ; 

  процедура   WithReflection  ; 
  вар 
   RttiContext  :   TRttiContext  ; 
    RttiType  :   TRttiInstanceType  ; 
    Фу  :   ТОбъект  ; 
  начать 
   RttiType   :=   RttiContext  .   FindType  (  'Unit1.TFoo'  )   как   TRttiInstanceType  ; 
    Фу   :=   RttiType  .   GetMethod  (  'Создать'  )  .   Вызов  (  RttiType  .  MetaclassType  ,   [])  .   КакОбъект  ; 
    попробуйте 
     РттиТип  .   GetMethod  (  'Привет'  )  .   Вызвать  (  Foo  ,   [])  ; 
    наконец 
     Фу  .   Бесплатно  ; 
    конец  ; 
  конец  ; 

ЕС [ править ]

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

// Без отражения 
 Foo   foo   {   }; 
  фу  .   привет  (); 

  // С отражением 
 Класс   fooClass   =   eSystem_FindClass  (  __thisModule  ,   "Foo"  ); 
  Экземпляр   foo   =   eInstance_New  (  fooClass  ); 
  Метод   m   =   eClass_FindMethod  (  fooClass  ,   »  ,   fooClass.module  «  привет  ); 
  ((  void   (  *  )())(  void   *  )  m  .  function  )(  foo  ); 

Иди [ править ]

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

import   "reflect" 

 // Без отражения 
 f   :=   Foo  {} 
 f  .   Привет  () 

 // С отражением 
 fT   :=   отражения  .   TypeOf  (  Foo  {}) 
 fV   :=   отражения  .   Новый  (  fT  ) 

 m   :=   fV  .   MethodByName  (  «Привет»  ), 
 если   m  .   IsValid  ()   { 
     м  .   Звонок  (  ноль  ) 
 } 

Ява [ править ]

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

импортировать   java.lang.reflect.Method  ; 

  // Без отражения 
 Foo   foo   =   new   Foo  (); 
  фу  .   привет  (); 

  // С отражением 
 try   { 
     Object   foo   =   Foo  .   сорт  .   getDeclaredConstructor  ().   новыйэкземпляр  (); 

      Метод   m   =   foo  .   ПолучитьКласс  ().   getDeclaredMethod  (  "привет"  ,   новый   класс  <?>[  0  ]  ); 
      м  .   вызвать  (  фу  ); 
  }   catch   (  ReflectiveOperationException   игнорируется  )   {} 

JavaScript [ править ]

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

// Без отражения 
 const   foo   =   new   Foo  () 
 foo  .   hello  () 

 // С отражением 
 const   foo   =   Reflect  .   конструкция  (  Foo  ) 
 const   hello   =   Reflect  .   get  (  foo  ,   'привет'  ) 
 Reflect  .   apply  (  hello  ,   foo  ,   []) 

 // С eval 
 eval  (  'new Foo().hello()'  ) 

Julia[editДжулия

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

julia>   struct   Point 
            x  ::  Int 
            y 
        end 

 # Проверка с отражением 
 julia>   fieldnames  (  Point  ) 
 (:x, :y) 

 julia>   fieldtypes  (  Point  ) 
 (Int64, Any) 

 julia>   p   =   Point  (  3  ,  4  ) 

 # Access с отражением 
 julia>   getfield  (  p  ,   :x  ) 
 3 

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

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

// Класс Фу. 
  @interface   Foo  :  NSObject 
 -   (  void  )  привет  ; 
  @end 

 // Отправка «привет» экземпляру Foo без отражения. 
  Foo   *  obj   =   [[  Foo   alloc  ]   init  ]; 
  [  объект   привет  ]; 

  // Отправка «привет» экземпляру 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  ->  $метод  ; 

  # или 
 $класс  ->  $конструктор  ->  $метод  ; 

  # с eval 
 eval   "new Foo->hello;"   ; 

PHP [ править ]

Ниже приведен пример на PHP : [6]

// Без отражения 
 $foo   =   new   Foo  (); 
  $foo  ->  привет  (); 

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

Питон [ править ]

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

# Без отражения 
 obj   =   Foo  () 
 obj  .   hello  () 

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

 # С eval 
 eval  (  "Foo().hello()"  ) 

Р [ править ]

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

# Без отражения, предполагая, что foo() возвращает объект типа S3, имеющий метод "hello" 
 obj   <-   foo  () 
 hello  (  obj  ) 

 # С отражением 
 имя_класса   <-   "foo" 
 generic_having_foo_method   <-   "hello" 
 obj   <-   do. вызов  (  имя_класса  ,   список  ()) 
 do.call  (  generic_having_foo_method  ,   alist  (  obj  )) 

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

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

# Без отражения 
 obj   =   Foo  .   новый 
 объект  .   привет 

 # С отражением 
 obj   =   Object  .   const_get  (  "Фу"  )  .   новый 
 объект  .   send   :hello 

 # С eval 
 eval   "Foo.new.hello" 

Содзё [ править ]

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

'Без отражения 
 Dim   fooInstance   As   New   Foo 
 fooInstance  .   PrintHello 

 ' С отражением 
 Dim   classInfo   As   Introspection  .   Typeinfo   =   GetTypeInfo  (  Foo  ) 
 Dim   Конструкторы  ()   As   Introspection  .   Информация о конструкторе   =   Информация о классе  .   GetConstructors 
 Dim   fooInstance   As   Foo   =   конструкторы  (  0  ).   Вызов 
 Dim   методов  ()   как   интроспекция  .   Информация о методе   =   Информация о классе  .   GetMethods 
 For   Each   m   как   самоанализ  .   MethodInfo   В   методах 
   If   m  .   Name   =   «PrintHello»   Тогда 
     m  .   Вызов  (  fooInstance  ) 
   End   If 
 Next 

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

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

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

  1. ^ Учебное пособие по поведенческой рефлексии и ее реализации Жака Маленфана и др. (PDF) , неизвестно, заархивировано из оригинала (PDF) 21 августа 2017 г. , получено 23 июня 2019 г.
  2. ^ Брайан Кантвелл Смит, Процедурная рефлексия в языках программирования , факультет электротехники и информатики, Массачусетский технологический институт, докторская диссертация, 1982.
  3. ^ Брайан С. Смит. Рефлексия и семантика в процедурном языке. Архивировано 13 декабря 2015 г. на Wayback Machine . Технический отчет MIT-LCS-TR-272, Массачусетский технологический институт, Кембридж, Массачусетс, январь 1982 г.
  4. ^ Баррос, Пауло; Просто, Рене; Мильштейн, Сюзанна; Вайнс, Пол; Дитль, Вернер; д'Аморим, Марсело; Эрнст, Майкл Д. (август 2015 г.). Статический анализ неявного потока управления: разрешение отражений Java и намерений Android (PDF) (отчет). Университет Вашингтона. UW-CSE-15-08-01 . Проверено 7 октября 2021 г.
  5. ^ Эувидум, Иеу; дисковый шум (5 октября 2021 г.). «Двадцать лет побега из песочницы Java» . Фрак . Том. 10, нет. 46 . Проверено 7 октября 2021 г.
  6. ^ «PHP: ReflectionClass — Руководство» . www.php.net .

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

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

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

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

Arc.Ask3.Ru: конец оригинального документа.
Arc.Ask3.Ru
Номер скриншота №: 695E05B04F04BFD3F08CF167FC4DD5DE__1718394900
URL1:https://en.wikipedia.org/wiki/Reflective_programming
Заголовок, (Title) документа по адресу, URL1:
Reflective programming - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть, любые претензии не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, денежную единицу можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)