來自:http://m.tkk7.com/Unmi/archive/2009/07/01/285020.html
作為 Java 程序員,對于 JavaBean 也許你會說再熟悉不過了,它貫穿在系統的多層中,不同的叫法有
PO、VO、DTO、POJO、DO(Domain Object)。然而它無外乎就是一個 Class 類,帶上些屬性和它們的
setter/getter 方法,set/get 后面那一個字母大寫。雖然我們現在很少把 JavaBean 與那個古老的 2.0 的 EJB
搞混,但為什么明明用 IDE 為屬性生成的 getter/setter 方法,應用一運行,還是報找不到某個 bean 屬性的 setter 或
getter 方法呢?
要知道,在 Sun 的網站上那個關于 JavaBean 規范的 PDF 文檔可是有足足實實的 114 頁啊。難免有些規則有點古怪,至使知名的 IDE 都難以應對,所以我們還是有必要了解其中二三,來規范我們的 JavaBean 和解釋一些情形。
Sun 的關于 JavaBean 規范見:http://java.sun.com/javase/technologies/desktop/javabeans/docs/spec.html,其中可下載到 JavaBean 規范的 PDF 文檔。
實際中的問題
首
先,當然還是要說它的屬性及 setter/getter 方法。屬性以小寫字母開頭,駝峰命名格式,相應的 getter/setter 方法是
get/set 接上首字母大寫的屬性名。多數情況是對的,且當前流行的 IDE(Eclipse、JBuilder) 也都認這個死理,這里
NetBean
值得表揚一下。但要是碰到些遺留的代碼中屬性名不規范,或者有些人就是頑固,或真是對屬性命名猶豫不決時的寫下的代碼時,那還是有得你研究一下。
這里來看看 Eclipse 為幾個屬性生成的 getter/setter 方法吧:
sName(從 C 轉過來的,受匈牙利的影響,認為 Name 是個字符串,所以加個前綴 s) getSName()/setSName(String name)
URL (平時認為是縮略語/專有名詞,理當全部大寫,這在我們對待 ID 時經常發生的) getURL()/setURL(String url)
上
面第一個由 Eclipse 為我們生成的 getSName()/setSName(String name) 方法,參照 JavaBean
規范來說,其實是錯誤的。如果出現這樣的方法,放到我們的標簽(像 Struts 標簽,如 <s:textfield
name="sName"/>),或是進行 Hibernate/iBatis 那種映射時,你就能收到報 找不到 sName 屬性相應的 getter/setter 方法 那樣的錯誤。不是明明有 getSName() 和 setSName(String name),可是方法名錯了,正確的版本應該是 getsName() 和 setsName(String name)。
前面首先解釋了屬性命名不規范產生問題的原因,現在就來更仔細的了解關于 JavaBean 屬性及其 getter/setter 方法的約定,有些是硬性的。
屬性與存取訪問的規定
為 JavaBean 創建屬性時,必須牢記:縮略語通常被視為一個獨立的單詞,而不是單個字母。例如,URL 對應的屬性名應該用 url,相應的 getUrl()/setUrl(),所以 ID 還是用 id 作為屬性吧,相應的 getId()/setId()。
規
范中另一個特別的地方就是,第二個字母為大寫的屬性名要區別對待。如果屬性名的第二個字母是大寫的,那么該屬性名直接用作 getter/setter
方法中 get/set 的后部分,就是說大小寫不變。這就是為什么 sName 對應的存取方法是 getsName()/setsName()
的原因,不能不說這條規則很令人費解。那就更有必要看看下面表格的規范:
屬性名/類型 |
getter 方法 |
setter 方法 |
xcoordinate/Double |
public Double getXcoordinate() |
public void setXcoordinate(Double newValue) |
xCoordinate/Double |
public Double getxCoordinate() |
public void setxCoordinate(Double newValue) |
XCoordinate/Double |
public Double getXCoordinate() |
public void setXCoordinate(Double newValue) |
Xcoordinate/Double |
不允許 |
不允許 |
student/Boolean |
public Boolean getStudent() |
public void setStudent(Boolean newValue) |
student/boolean |
public boolean getStudent()
public boolean isStudent() |
public void setStudent(boolean newValue) |
屬
性是首字母大寫,次字母小寫是,你永遠都找不到它的 getter/setter 方法的,對這個屬性的使用是會害人的。對于 boolean
類型屬性的 getter 方法是 isXxx() 還是 getXxx() 就自己決定了,isXxx() 應該更接近于自然語言,更順溜些。
知道了屬性及存取方法的規定,那么你即使是面對古老代碼,在使用標簽來引用或與 Hibernate/iBatis 等進行映射,你就知道該填什么樣的屬性名了。
還有一個我們很少碰觸到的是關于可索引屬性的 getter/setter 方法(這方面 C# 表現的比 Java 要優秀),比如有屬性
private OrderItem[] orderItem; 那它相應的 getter/setter 除常見的兩個外,還有帶索引參數的兩個版本,如下:
public OrderItem[] getOrderItem();
public void setOrderItem(OrderItem[] newArray);
public OrderItem[] getOrderItem(int index);
public void setOrderItem(int index, OrderItem orderItem);
關于 Bean 導航
最后就是 Bean 導航的規范,通常用點記法(dot notation) 來引用屬性,同時也要注意索引屬性的訪問。在 Web MVC 的表單中,以及標簽中, Jarkata-Commons-BeanUtils 中用得很多??袋c記法的示例:
Java 代碼 |
點記法 |
anOrder.getAccount().getUsername() |
anOrder.account.username |
anOrder.getOrderItem().get(0).getProductId() |
anOrder.orderItem[0].productId |
anObject.getId() |
anObject.id |
anObject.getxCoordinate() |
anObject.xCoordinate |
上表應該從右往左邊看,點記法中的屬性名運行時要被解析成相應的存取方法調用。比如像 Struts1 標簽:
<html:text property=
"stocks[1].code"/>
會顯示出 FormBean 中 stocks 列表的第二個元素的 code 屬性,提交就填充到相應的位置上去。