我們都知道作為一名程序員,經常進行代碼注釋是一種很好的習慣。但你的后臺代碼需要更改的時候,我們不需要將整片的代碼進行改寫,那么這個時候,注釋就顯得重要了。它能幫你快速找到需要修改的區(qū)域,也不用一行一行的去尋找。其實Java注釋還有一個故事,一個你不知道的故事。
1.XML大臣
最近這幾年,XML大臣的宅邸車水馬龍,像什么Spring, Hibernate, MyBatis 等大大小小的官員進京來都要拜訪一下,無數的冰敬碳敬悄悄地送入府中, 真可謂紅極一時, 正處于人生巔峰。 原因很簡單,Java帝國的配置文件幾乎都在使用XML, 自然都歸XML大臣管理,想不紅都難!
其他大臣看在眼里,恨在心里,他們決定聯(lián)合起來,堅決打擊XML大臣的囂張氣焰, 堅決把白花花的銀子轉移到自己府中來。 幾位老家伙商量以后,決定還是推舉老成持國的IO大臣為首領,給XML大臣一點顏色瞧瞧。
2.安翰林獻計
可是IO大臣想了半天,也沒什么好辦法。
這一天有個姓安的翰林自報家門求見, 說是可以助IO大臣一臂之力。
“安大人有何見教?” IO大臣懶洋洋地問道,他對這些讀死書的翰林們沒什么好感。
“大人,下官在負責Java注解,對付XML大臣,也許是個突破口”
“注解? 這是什么東西?” IO大臣確實是有點老了
“其實就是元數據了”
“元數據?” IO大臣一頭霧水。
“嗯, Metadata” 安翰林把英文都整出來了。
“賣它推它?” IO大臣明顯英文不好。
旁邊的幕僚一個勁兒的使眼色, 諄諄告誡安翰林要通俗易懂。
安翰林說: “大人肯定知道@Override,@SuppressWarning等注解吧? ”
IO大臣點頭。
安翰林接著說: “所謂元數據, 就是描述數據的數據了,換句話說可以給其他數據提供描述性信息, 例如Java類中的某個方法,可以認為是一種數據, 如果我的@Override 一旦被用到這個方法上,那就意味著要覆蓋父類/接口的方法了,于是我的@Override 就給這個方法提供了額外的信息。”
“但是在源代碼中寫個@Override 似乎也沒什么用處啊? ” IO大臣問道
“所以這只是元數據, 它給其他數據(如Java方法)提供了信息, 但是怎么樣利用這些信息那就不歸我管了。”
“那歸誰管?”
“比如@Override , 由編譯器來管,當編譯這個Java 文件的時候,它就會檢查被@Override 修飾的方法是否和父類的方法和參數相同, 如果不同,就會報錯了。”
IO大臣說: “奧,明白了,所謂的注解有點像加強版的注釋, 這個“注釋”不但有一定的格式,還有特定的含義,這樣別的工具就可以讀取它來做事情了!”
安翰林松了一口氣, 心里暗自佩服IO大臣的總結能力。
“我記得這個@Override注解很早就有了啊,好像是JDK1.4吧”
“沒錯, 之前JDK內置了@Override、@Deprecated 、@SuppressWarnings等注解, 但是用處不大, 下官有個想法,干脆允許臣民們自定義注解得了” 安翰林開始切入正題。
“自定義? 就是讓臣民們自己寫? ”
“是的大人, 比如我可以自定義一個叫做 @Test的 注解:” 安翰林說著把寫好的代碼呈了上去。
安翰林接著說: 大人請看我這里定義了一個叫做Test的注解,它有個ignore方法, 一會兒您老就看到它的用途了, 這個注解是應用在方法上的 @Target(ElementType.METHOD), 在運行時起作用@Retention(RetentionPolicy.RUNTIME)。
IO大臣問道:“稍等, 我怎么還看到了@Target,@Retention, 這是什么? ”
“這稱為元注解,可以認為是注解的注解。” 安翰林嘿嘿一笑說 “@Target表示該注解的應用目標,可以是類、方法、 方法參數等等, @Retention表示這個注解要保留到什么時候, 可以只在源碼中, 或者class 文件中, 或者是運行時。”
“ 注解的注解, 真是夠拗口的啊, 這個自定義的注解@Test 該怎么使用呢? ”
安翰林又展示了另外一段代碼:
IO大臣看了下,心想這自定義的注解和JDK內置的注解都差不多嘛,@Test修飾了方法, 表示這個方法可以作為測試用例來運行, @Test(ignore=true)則表示雖然這是個測試方法, 但是暫時忽略,不用運行, 果然簡潔而清爽,老夫真是小看了這個安翰林。
“@Test注解的定義和使用,只是定義了行為語義,怎么樣實現這個行為呢? ” IO大臣問道
安翰林早有準備:“大人請看,我可以在運行時通過反射的方式取出把方法的注解,如果這個注解是@Test, 并且沒有被ignore , 那就可以通過反射去執(zhí)行這個方法了, 是不是很簡單?”
IO大臣微微點了點頭,表示贊同,接著便閉目陷入了沉思: 這個東西有點意思,在一個方法上添加了簡單的修飾性注解@Test以后,這個方法突然間就有了額外的語義,變成了可以執(zhí)行的測試用例了 !
如果是XML老頭兒, 該怎么描述類似的行為呢? 也許得這樣:
相比于簡潔的@Test注解,這個方式實在是太復雜了, 更重要的是每次增加新的方法,除了修改Java文件之外,還得記著修改這個XML文件, 實在是繁瑣。
嗯, 看來這個注解確實是個殺手锏, 要謹慎使用,一擊必中。
想到這里,IO大臣睜開眼睛,喜笑顏開,讓安翰林寫一個關于注解的詳細奏章,自己在合適的時候呈給皇上。
3.早朝爭斗
初六陽光燦爛,IO大臣看到早朝的皇上心情不錯,就把奏章呈了上去。
“注解? 這是什么東西?” 皇上根本沒心思了解細節(jié)。
“啟奏陛下,這個注解能夠部分的代替一些XML的配置工作” IO大臣一邊小心翼翼地回復,一邊用余光向XML大臣掃去。
看到IO大臣向自己發(fā)難, XML大臣立刻警覺起來, 他馬上說: “陛下,可否讓老臣一觀?”
皇帝示意讓呂公公把奏章遞給XML大臣。
XML大臣看了一會兒就明白大事不好, 這簡直是釜底抽薪, 如果這個帝國批準了這個玩意兒,允許臣民們自定義注解,自己的勢力要大大地被削弱了。
XML大臣腦海中出現一副可怕的場景, Spring, Struts, Hibernate 等紛紛倒戈,都采用注解來進行系統(tǒng)配置,白花花的銀子開始流向IO大臣的府邸。。。。。。
不, 堅決要把這點星星之火迅速撲滅。
“陛下,依老臣之見, 此法斷不可行!” XML大臣斬釘截鐵。
“為何不可行? 使用注解,配置靠近代碼,容易閱讀、容易修改!” IO大臣立刻反擊, 為了展示易讀易改,IO大臣還現場寫了一段代碼,描述了一個普通的Java 類是如何向數據庫表和列映射的。 朝中多位大臣齊聲喝彩, 為IO大臣搖旗吶喊。
“單獨看一個當然很清晰, 但是如果多了, 配置分散在各個Java文件中, 極難查找,到時候你哭都來不及, 如果你用了XML, 所有的配置集中在一處, 一目了然。 還有,如果你想修改配置就得改Java源文件,重新編譯部署,這也太扯了吧?!” XML大臣不甘示弱。
眼看著兩位重臣開始劍拔弩張, 皇帝決定出面和稀泥, 他也不希望一家獨大,也想平衡一下朝中關系。
“兩位愛卿,依朕之意,還是先在JDK中加入自定義注解的支持,至于是用注解還是用XML, 還是讓朕的子民們去選擇吧! ”
看到皇上主意已定, 兩位大臣只好退下。
自定義注解發(fā)布了, 令大家沒有想到的是,無論是注解還是XML配置都沒有占據壟斷地位,很多人把二者混合起來使用了! 對于一些需要集中配置的場合,例如數據源的配置, 自然是用XML。 另外一方面對于@Controller, @RequestMapping, @Transactional 這樣的注解 , 大家更喜歡和Java方法寫在一起,顯得簡單而直觀。
這正如朝中的局勢,沒人能夠一家獨大,XML大臣雖然丟失了一些領地,但依然是不可忽視的力量。 一場爭斗,唯一的大贏家可能就是安翰林了,他被任命為Annotation大臣,專門管理自定義的注解。
評論
查看更多