反射是指在程式執行期對程式本身進行訪問和修改的能力,即可以在執行時動態獲取變數的各種資訊,比如變數的型別(type),類別(kind),如果是結構體變數,還可以獲取到結構體本身的資訊(欄位與方法),通過反射,還可以修改變數的值,可以呼叫關聯的方法。
反射常用在框架的開發上,一些常見的案例,如json序列化時候tag標籤的產生,介面卡函式的製作等,都需要用到反射。反射的兩個使用常見使用場景:
go程式的反射系統無法獲取到乙個可執行檔案空間中或者是乙個包中的所有型別資訊,需要配合使用標準庫中對應的詞法、語法解析器和抽象語法樹( ast) 對原始碼進行掃瞄後獲得這些資訊。
貼士:
注意:
反射是通過介面的型別資訊實現的,即反射建立在型別的基礎上:當向介面變數賦予乙個實體型別的時候,介面會儲存實體的型別資訊。
go中反射相關的包是reflect
,在該包中,定義了各種型別,實現了反射的各種函式,通過它們可以在執行時檢測型別的資訊、改變型別的值。
變數包括type、value兩個部分(所以nil != nil
),type包括兩部分:
型別能夠斷言成功,取決於 concrete type ,如果乙個reader變數,如果 concrete type 實現了 write 方法,那麼它可以被型別斷言為writer。
go中,反射與inte***ce型別相關,其type是 concrete type,只有inte***ce才有反射!每個inte***ce變數都有乙個對應的pair,pair中記錄了變數的實際值和型別(value, type)。即乙個介面型別變數包含2個指標,乙個指向對應的 concrete type ,另乙個指向實際的值 value。
示例:
var r io.reader // 定義了乙個介面型別
r, err := os.
openfile()
// 記錄介面的實際型別、實際值
var w io.writer // 定義乙個介面型別
w = r.
(io.writer)
// 賦值時,介面內部的pair不變,所以 w 和 r 是同一型別
reflect 提供了2個重要函式:
type person struct
p := person
fmt.
println
(reflect.
valueof
(p))
// 變數的值
fmt.
println
(reflect.
valueof
(p).
type()
)// main.person 變數型別的物件名
fmt.
println
(reflect.
typeof
(p))
// main.person 變數型別的物件名
fmt.
println
(reflect.
typeof
(p).
name()
)// person:變數型別物件的型別名
fmt.
println
(reflect.
typeof
(p).
kind()
)// struct:變數型別物件的種類名
fmt.
println
(reflect.
typeof
(p).
name()
=="person"
)// true
fmt.
println
(reflect.
typeof
(p).
kind()
== reflect.struct)
//true
型別與種類的區別:
靜態型別:變數宣告時候賦予的型別
type myint int
// int 是靜態型別
var i *
int// *int 是靜態型別
動態型別:執行時給這個變數賦值時,這個值的型別即為動態型別(為nil時沒有動態型別)。
var a inte***ce
// 空介面 是靜態型別,必須是介面型別才能實現型別動態變化
a =10// 此時靜態型別為 inte***ce{} 動態為int
a ="hello"
// 此時靜態型別為 inte***ce{} 動態為string
反射 Class物件功能概述
class物件功能 獲取功能 1.獲取成員變數們 field getfields 獲取所有public修飾的成員變數 field getfield string name 獲取指定名稱的 public修飾的成員變數 field getdeclaredfields 獲取所有的成員變數,不考慮修飾符 f...
反射專題1
1 首先,先解決乙個問題,完成乙個物件的拷貝。2 獲取class 型別的物件方法 1 通過getclass 方法,如 person類 reflection 類 輸出 可見某個型別的多個物件在共享乙個class型別物件。2 通過class.forname string name 方法,如 在原來per...
反射理解1
web框架的核心在於反射。這需要操作xml檔案和class物件來實現。反射應用於在編譯時無法知道傳遞過來的引數是什麼物件,只有在執行時才知道的情況下。通過反射能獲取已裝載類的屬性 方法 構造方法等資訊。它將程式 訪問裝載到jvm中的類的內部資訊。class物件 獲取class物件的方法 1 通過cl...