close

需要上課的人員:

  1. 不瞭解JAVA Reflection的人員。

  2. 不瞭解Struts 2 中,JAVA的變數為何可以在JSP中使用的人員。

JAVA Reflection(映射)

在寫程式的時候,有時候會遇到一些比較特殊的情況,例如我有一個Class如下:

我想將它轉為JSON的格式,變成{name:"myname",age:18}這樣之類的,除了利用套件自動生成外,另一種方式是自己寫,如下:

可是這樣會遇到二個問題,第一個問題是:當我這個class因業務需求,加了一個屬性後,產生JSON的這段程式碼也要跟著變;第二個問題是:當我今天有N個屬性,我就是針對jObject.put這一段程式碼寫N次。難道不能讓它自動對應產生嗎?答案是可以的,這種對應的方法叫做Reflection。

Reflection的Field、Method定義

在JAVA的Reflection中,有一個專有名詞是Field,Field定義的是Class中的屬性,如下圖紅框的部份:

而Method的定為則為下方的紅框處:

這些定義都會在程式裡被用到。

JAVA Reflection實作

要利用Reflection的機制,必須先取得這一個Class,才能取得Class內的Field或Method,取得Class的方法很簡單,利用getClass即可,如下圖:

取得Class後,以本例來說,我們需要取得Class內的Field,所以透過getDeclaredFields的Method來取得這個Class內的Field。

我們可以利用Field的getName()來取得對應的變數文字,在本例中即是name與age。

再利用Field的get(Object o),此時傳入的參數為想要取得值的Object,也就Employee的物件。最後我們利用for each的方式,來取得每一個Field的name與Value,並將它塞入JSONObject中:

執行後的結果:

這就是Reflection的其中一種應用,另外Method是透過invoke的method來觸發,下方是網路上的範例:

Reflection很好用,但一開始不太好理解,需要多寫幾次才能理解。

JAVA命名規則

JAVA有一些命名規則,大致介紹如下:

  • Class:頭文字大寫,第二單詞以大寫相接。

  • Field變數:頭文字小寫,第二單詞以大寫相接。

  • Method:頭文字小寫,第二單詞以大寫相接。

  • Constant:全文字大寫,第二單詞以_(底線)相接。

 

如下圖範例:

遵守這些命名規則有什麼好處呢?因為有很多Framework是套用JAVA的命名規則來實作JAVA Reflection,所以這些Framework都是假設我們已經遵守這些命名規則了。

Framework與命名規則與Reflection實例

大多數的Framework在實作Reflection的功能時,是以Method的方式來實作的,而不是利用Field,這一點要請大家搞清楚,而且因應時機的不同,分別去觸發的Method也不同,以下圖的Struts2程式為例:

UserAction.java的程式碼如下:

JSP中的程式碼如下:

我們可以看到幾個重點:

  1. 在Action中的Method與Field是不相稱的,Method是setQ,而Field是query。

  2. 在JSP中的程式碼,name的屬性為q,所以送到後端時會變為q=xxx之類的參數。

這代表著前端使用者輸入的內容,在Action中會觸發setQ的Method,把值設進Field query之中。在這種狀況中,被觸發的Method是setQ,而且它並不會判斷是否有Field q及Method getQ存在與否(實際上並沒有getQ這個Method被宣告)。

上方的範例可以得到二個重點:

  1. Method與Field可以不對稱。

  2. set與get並不需要同時存在,而是視需求來撰寫。

Struts 2 其實是根據Request與Response來決定要呼叫get或set,Request時呼叫的是set Method,Response時呼叫的是get Method,這點請大家記清楚。

已實作Reflection的Framework

我們來談談有那些東西是套用命名規則與Reflection的套件吧:

  1. Struts2

  2. EL

  3. JSTL

  4. net.sf.json

  5. Volecity

….等等,有太多的Framework都會實作Reflection,並利用「.」來區隔物件,例如user.name是先取得變數user的Object後,再去取得這個Object內的getName;所以請開發人員瞭解JAVA的命名規則,並實際運用在寫程式上,因為這些Framework都是以開發人員已經使用JAVA的命名規則為基礎來開發的。

作業-實作Reflection中的Method

請依下方的程式碼,實作setName與getName的Method。

arrow
arrow

    JAVA Programmer 發表在 痞客邦 留言(0) 人氣()