2025-02-10

隨著J2EE進入5.0時代後,Java EE5.0的很多特性也被廣泛應用在J2EE程序中。而Java EE5.0的註釋(Annotations)特性就是其中應用最廣泛的特性之一。


  如果稍微瀏覽一下最新的Java EE5.0(EJB3.0,JPA)的標準規范,就可以發現,這些規范的制定者或是支持者們宣稱最多的莫過於,利用這些規范可使開發變得像開發POJOs一樣的簡單與簡潔。但是,如果對那些源代碼稍加瀏覽或查看,最引人註目的可能就是那些取代瞭XML描述作用的註釋。那麼,筆者們禁不住要問一句,註釋的使用真的可以簡化復雜的J2EE或組件的開發嗎?


  一、引言


  在以前的J2EE版本中,都是使用大量的配置文件來設置Web程序、EJB等。但這一切在Java EE5.0中得到瞭徹底的改善。Java EE5.0中的註釋(Annotation)是專門針對Web和EJB程序而設計的。如@Resource、 @EJB和@WebServiceRef等,以及其它一些與安全相關的註釋,如@RunAs和@DeclareRoles。


  在Java EE5.0中,這種對元數據(Meta-data)的支持的數據就是註釋。通過使用註釋, 程序開發人員可以在不改變原有邏輯的情況下,在源文件嵌入一些補充的信息。代碼分析工具、開發工具和部署工具可以通過這些補充信息進行驗證或者進行部署。舉個例子,例如希望某個方法的參數或者返回值不為空,雖然可以在Java doc中進行說明,但是表達同樣意思的作法有很多,比如“The return value should not be null”或者“null is not allowed here”。測試工具很難根據這些語言來分析出程序員所期望的前提條件(Pre-condition)和執行後的條件(Post-condition)。而使用註釋(Annotation),這個問題就可以輕而易舉的解決。


  註釋,簡單的說,就是代碼裡的標記,這些標記可以在類加載、運行時或是編譯的時候可以被解釋。這給人的感覺極像C++的macros。


  其實說起註解語法,對於任何一個Java開發人員來說都已經耳熟能詳瞭,我們每天都在使用著 的@author、 @param等等,其實都是在編寫註釋,然後用Javadoc生成文檔。Java的這種方便的文檔生成方法受到瞭開發者的普遍贊譽。而從JDK1.5開始,註釋語法提供瞭更為強大的功能。


  二、註釋——真的能簡化嗎?


  筆者問過一些做Java開發的朋友關於對註釋的瞭解情況。很多都說,在實際的項目當中,依然在使用Java1.4及EJB2.0,因為還沒有到不得不使用註釋的時候。當然,在平時的學習當中,可能會有涉及到註釋。


  註釋是代碼文件中的偽代碼,而代碼之外的一些配置文件,如XML及*.properties,感覺更加容易從編譯過的部署類裡具體化。這兩者可能各有優點,那我們普通的開發人員依據什麼來決定,到底是把元數據寫在源文件代碼裡,還是寫在單獨的配置文件中呢?


  有一點可以肯定,其它能像Java這樣提供註釋功能的語言並不多。引入註釋的目的無非就是想把一些需要單獨或是額外解決的問題,引用於源文件中一並解決,但這並不一定能起到藥到病除的效果。


  讓我們看看使用註釋在類文件中寫入配置信息的情況:這意味著需要重新編譯才能反映配置信息的改變,配置不能在Java程序外面單獨的加以操作與配置。同時,對於使用那些支持註釋及非註釋兩種類型的框架,無疑會使項目的配置更加混亂,增加維護難度。


  如果一個軟件在試運行或是真正使用時,碰到用戶需求變化或者原來功能不能正常運行,如果一些基本的配置信息都寫進Java源文件中,一般的作法是:需求反饋到該程序設計程序員,程序員修改代碼,再進行測試,可能測試不通過,影響其他功能瞭,再測試,折騰很長時間,最後編譯打包,交付客戶。


  如果使用XML和Java分離方式:水平較低的維修人員趕到現場,修改一下配置XML,無須編譯Java代碼,測試,馬上解決問題。很明顯哪個更快呢?


  所以,開發軟件不能隻顧自己開發時方便,還要考慮到運行維護時是否方便,軟件不像冰箱,制作好交給用戶,很堅固,很穩定,用戶也不會提出什麼修改意見,當然海爾的定制化冰箱有這個意思,但是這種水平不是一般廠商水平能夠做出來的。


  當然,筆者並不反對或是拒絕任何可以提高軟件開發效率及節約時間的方法或技術,但這有個前提,就是這種技術或方法的成本或是代價。有些人會說,將一些部署邏輯或是信息嵌入在代碼中,這樣可以減少文件的間接訪問,增加代碼的集中度。但是,在一個滿是註釋的源文件中,去提取特定的配置註釋,這無疑會增加代碼的分析時間。此外,筆者們又如何給那些沒有源文件的類文件進行註釋呢?最後,註釋又為何要整一套自己的新語法?它本來就像Java語法,那有必要另起爐灶,再整一套自己的語法嗎?


  當然,筆者也承認,註釋有它肯定的一面,並且可以肯定,其初衷是好的。但筆者認為,在EJB3.0規范中,其註釋的規范有些太過極端瞭。因為很明顯,這已經違背瞭軟件的簡易性原則,增加瞭開發的復雜性,使代碼的可維護性降低瞭。


  三、註釋——使J2EE開發變得容易一些


  我們知道,註釋其實也是一種修飾符,在可以使用其它修飾符(比如public,static,或 final)的任何地方都可以使用註釋。按規定,註釋優先於其它修飾符。它包括一個@符號,@後接註釋類型和被括號括起來的元素值對。這些值必須是編譯時常量。也就是說 Java本身就提高瞭註釋信息的詳細列表。註釋並不直接影響程序的語義,但它影響工具和庫處理程序的方式,從而對運行程序的語義產生影響。註釋可從源文件、class文件中閱讀,也會在運行時得到反映。將定義從執行中分離出來並提供一種可以內省約束的方式,這使得執行過程更加靈活。大多數Java開發者已經很熟悉註釋瞭,比如所有的JavaDoc標簽和瞬時標簽都是註釋的例子。


  普遍的觀點都認為,配置信息最好不要使用註釋寫在源文件中,因為這樣需要每次編譯修改過註釋的類,最好是將其寫成單獨的XML等文件。


  任何J2EE 開發者都知道開發Java 程序其實並不簡單。但新的Java EE 5.0將使你的開發過程變得容易一些。Java EE 5.0具有Web 服務支持、註釋和增強的CMP性能。


  要開發一個簡單的J2EE應用程序,程序員必須要寫大量的樣本文件代碼(如JavaBeans企業版)和設定無數個配置文件(XML中的描述文件)。所以要成為一個J2EE開發者,程序員必須熟悉EJB和XML。對於初學者來說,這些將令他們望而生畏。


  目前的J2EE說明書(1.4)非常長,是用較老的JDK 1.2版本寫的,這使J2EE更加復雜難懂。新的JDK版本提供瞭豐富的、簡單好用的性能,比如Java EE 5.0的一般性能和註釋支持。


  而最新的Java EE 5.0,其中一個主要目的就是,既保持J2EE強大的功能,又可以使一般的開發任務變得容易一些。為瞭達到這個目的,Java EE 5.0將提供更好的默認性態和設置,允許大多數容器無需使用部署描述符就可以得到需要的東西。為此,Java EE 5.0做瞭很多註釋。開發者不需要知道執行的細節(由容器完成執行任務)。這些新性能都使企業的Java應用程序更小、更快。


  四、註釋——有所為,有所不為


  註釋作為元數據的保存或是持有是很實用的。例如,在構建一個實體類或是控制器時變得很方便。同時,在兩個不同類之間進行關聯時也很有用。


  但是,如果把註釋作為配置目的來使用,則有違它最初的設計初衷。因為配置文件或信息是經常需要修改的,例如數據庫的映射文件等,在這方面使用註釋,顯然有濫用或過分使用的成分。因此,在這方面,Java EE5.0及Hibernae走得有點偏瞭,這常常使得註釋在元數據與配置文件之間混用。


  但是,這並不能說註釋是有問題的,隻能說是使用者誤用問題造成的。註釋比較適合用於元數據的定義或保存。但並不適用於應用運行的配置信息。


  此外,註釋另外一個很成功的應用可能就是在JUnit4 API裡的應用。如:


  增加一個@Test註釋,而不需要像以前那樣寫成testXxx();


  增加一個@Test註釋,就可以替代以前的try/catch出錯處理瞭;


  增加一個@Before@After註釋,可以替換以前的setUp()等方法;


  增加一個@RunWith(Parameterized.class)及一個方法@Parameters public static Collection parameters(),被測試類的構造參數都保存在Object[]裡。這樣就進行參數化的測試瞭,而無須像從前那樣public static Test suite()。


  據筆者所知,JUnit框架中註釋的使用,的確使它變成更加的靈活,代碼更加的緊湊。


  其實,註釋隻是我們普通開發人員手裡的一個工具,它也許是一個新玩意,帶有幾分的新鮮,但也有幾分的討厭,其實也是一把雙刃劍。筆者記得當初學習設計模式的時候,就想把所有的這些模式趕快應用到開發當中,不管適用不適用。隻有當這種新鮮感過後,才能正常與正確的使用這些新特性。


  五、小結


  那註釋到底用還是不用呢?筆者認為,把註釋應用到有意義的地方,而不是一味的濫用即可。例如,在那些沒有註釋就不能運行的地方肯定需要就註釋。再如,改變註釋將可能導致運行時類的行為,那可以考慮使用註釋。


  Java EE5.0使用註釋這樣新語法,替代XML,當然,修改元註釋還是需要重新編譯的,這和修改源碼沒有兩樣,但是如果沒有單元測試這一人工工程管理跟上,程序上線正式運行,因為粗心等各種瑣碎問題全部爆發,更是可怕。


  另外,筆者認為,ROR中的約定優於配置(Convention Over Configuration ),這種做法Java的框架可以借鑒一下,在前期把問題都解決,這總比到瞭維護實施後期左找右改XML要強吧,犧牲瞭靈活性得到的卻是可靠和穩定。使用ROR這樣的解釋語言,對於註釋的修改是不需要編譯,當然約定優於配置不是ROR首先提出來,默認簡單,容易上手,需要細節還是可以使用XML配置。總之,約定優於配置是基於XML基礎上的改進。當然,筆者不反對探索簡化,但是目前探索結果還是發現,XML比較穩定,符合分離OO思想,能夠健壯

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *