在計算機學中，反射式程式設計或反射，是指計算機程式在執行時可以訪問、檢測和修改它本身狀態或行為的一種能力。見。用比喻來說，反射就是程式在執行的時候能夠 觀察 並且修改自己的行為。 要注意術語 反射 和 內省的關係。內省（或稱 自省）機制僅指程式在執行時對自身資訊（稱為元資料）的檢測；反射機制不僅包括要能在執行時對程式自身資訊進行檢測，還要求程式能進一步根據這些資訊改變程式狀態或結構。 概況 反射用於觀察並修改程式在執行時的行為。一個反射導向的程式元件可以監測一個範圍內的程式碼執行情況，可以根據獲取的目標物件資訊及與此相關的範圍修改自身。這可透過在執行時動態分配程式程式碼實現。 在型別檢測嚴格的面向物件的程式語言如 Java 中，一般需要在編譯期間對程式中需要呼叫的物件的具體型別、介面（interface）、資料成員（fields）和方法的合法性進行檢查。反射技術則允許將對需要呼叫的物件的訊息檢查工作從編譯期間推遲到執行期間再現場執行。這樣一來，可以在編譯期間先不明確目標物件的介面（interface）名稱、欄位（fields），即物件的資料成員（成員變數）、可用方法，然後在執行根據目標物件自身的訊息決定如何處理。它還允許根據判斷結果進行例項化新物件和相關方法的呼叫。 反射主要用途就是使給定的程式，動態地適應不同的執行情況。利用物件導向建模中的多型（多型性）也可以簡化編寫分別適用於多種不同情形的功能程式碼，但是反射可以解決多型（多型性）並不適用的更普遍情形，從而更大程度地避免硬編碼（即把程式碼的細節 寫死，缺乏靈活性）的程式碼風格。 反射也是超程式設計的一個關鍵策略。 歷史背景 早期計算機的原生組合語言本質上就具有反射特性。因為這些最初架構可以透過定義指令作為資料及使用自修改程式碼來程式設計，實現反射功能是很平常的。程式設計發展到使用編譯型高階語言如 Algol、Cobol、Fortran 和包括 Pascal 和 C 在內的很多其他語言時，自修改程式碼等實踐很大程度上消失了，直到將反射特性內建入型別系統的高階程式語言出現後才再次提供了反射功能。Lisp 語言家族以具有同像性作為標誌性特徵，可以認為具有反射性。 1982 年，在其博士論文《程式語言中的過程式反射》中 Brian Cantwell Smith Procedural Reflection in Programming Languages Department of Electrical Engineering and Computer Science Massachusetts Institute of Technology PhD dissertation 1982，向程序式程式設計語言介入了 計算反射 的概念，並且引入自迴圈直譯器概念用作 3Lisp 的一個組成部份。 特點 優點 支援反射的語言提供了一些在早期高階語言中難以實現的執行時特性。 可以在一定程度上避免硬編碼，提供靈活性和通用性。 可以作為一個頭等物件發現並修改原始碼的結構（如程式碼塊、類、方法、協議等）。 可以在執行時像對待原始碼語句一樣動態解析字串中可執行的程式碼（類似 JavaScript 的 eval 函式），進而可將跟 class 或 function 匹配的字串轉換成 class 或 function 的呼叫或引用。 可以建立一個新的語言位元組碼直譯器來給程式設計結構一個新的意義或用途。 劣勢 此技術的學習成本高。面向反射的程式設計需要較多的高階知識，包括框架、關係對映和物件互動，以實現更通用的程式碼執行。 同樣因為反射的概念和語法都比較抽象，過多地濫用反射技術會使得程式碼難以被其他人讀懂，不利於合作與交流。見。 由於將部分資訊檢查工作從編譯期推遲到了執行期，此舉在提高了程式碼靈活性的同時，犧牲了一點點執行效率。 透過深入學習反射的特性和技巧，它的劣勢可以儘量避免，但這需要許多時間和經驗的積累。 例子 下列程式碼片段建立類 Foo 的一個例項 foo，並呼叫它的方法 PrintHello。對於每個程式語言，展示平常的和基於反射的呼叫序列。 C Without reflection Foo foo new Foo fooPrintHello With reflection SystemObject foo2 SystemActivatorCreateInstance SystemTypeGetType completeclasspathandFoo SystemReflectionMethodInfo method foo2GetType GetMethod PrintHello methodInvoke foo2 null Go import reflect Without reflection f Foo fHello With reflection fT reflectTypeOf Foo fV reflectNew fT m fVMethodByName Hello if mIsValid mCall nil Java import javalangreflectMethod Without reflection Foo foo new Foo foohello With reflection try Alternatively Object foo FooclassnewInstance Object foo ClassforName completeclasspathandFoonewInstance Method m foogetClass getDeclaredMethod hello new Class0 minvoke foo catch Exception e Catching ClassNotFoundException NoSuchMethodException InstantiationException IllegalAccessException Perl Without reflection my foo Foonew foohello or Foonewhello With reflection my class Foo my constructor new my method hello my f classconstructor fmethod or classconstructormethod with eval eval new Foohello PHP Without reflection foo new Foo foohello With reflection using Reflections API reflector new ReflectionClass Foo foo reflectornewInstance hello reflectorgetMethod hello helloinvoke foo Python Without reflection obj Foo objhello With reflection obj globals Foo globals Return a dictionary representing the current global symbol table getattr obj hello getattr object name Return the value of the named attribute of object With eval eval Foo hello R Without reflection assuming foo returns an S3type object that has method hello obj foo hello obj With reflection theclass foo themethod hello obj docall theclass list docall themethod alist obj Ruby Without reflection obj Foonew objhello With reflection class_name Foo method_name hello obj Objectconst_get class_namenew objsend method_name With eval eval Foonewhello 常見應用 反射經常作為軟體測試的一部分，比如執行時建立 例項化模擬物件。 Java 語言解析 XML 檔案的技術用到了反射。 參見 程式自修改 反射式程式語言和平臺列表 參考資料 引用 來源 外部連結 Reflection in logic functional and objectoriented programming a short comparative study An Introduction to ReflectionOriented Programming Brian Footes pages on Reflection in Smalltalk Java Reflection API Tutorial from Oracle Category 程式設計典範