注释,无处不在的注释
十年前的2004年 , Java 1.5開始提供注釋。 很難想象沒有此功能的代碼。 實(shí)際上,首先引入了注釋,以減輕開發(fā)人員編寫繁瑣的樣板代碼的痛苦,并使代碼更具可讀性。 考慮一下J2EE 1.4(沒有可用的注釋)和Java EE5。注釋的采用通過消除所有配置XML大大簡(jiǎn)化了Java EE應(yīng)用程序的開發(fā)。 即使在今天,更多的注釋仍被添加到最新版本的Java EE中。 這樣做的目的是減輕開發(fā)人員的負(fù)擔(dān)并提高生產(chǎn)率。 其他技術(shù)和框架也廣泛使用它們。
到處都有注釋
讓我們看一個(gè)有關(guān)注釋如何簡(jiǎn)化代碼的示例(摘自我有關(guān)JPA實(shí)體圖的文章 ):
電影.java
@Entity @Table(name = "MOVIE_ENTITY_GRAPH") @NamedQueries({@NamedQuery(name = "Movie.findAll", query = "SELECT m FROM Movie m") }) @NamedEntityGraphs({@NamedEntityGraph(name = "movieWithActors",attributeNodes = {@NamedAttributeNode("movieActors")}),@NamedEntityGraph(name = "movieWithActorsAndAwards",attributeNodes = {@NamedAttributeNode(value = "movieActors", subgraph = "movieActorsGraph")},subgraphs = {@NamedSubgraph(name = "movieActorsGraph",attributeNodes = {@NamedAttributeNode("movieActorAwards")})}) }) public class Movie implements Serializable {@Idprivate Integer id;@NotNull@Size(max = 50)private String name;@OneToMany@JoinColumn(name = "ID")private Set<MovieActor> movieActors;@OneToMany(fetch = FetchType.EAGER)@JoinColumn(name = "ID")private Set<MovieDirector> movieDirectors;@OneToMany@JoinColumn(name = "ID")private Set<MovieAward> movieAwards; }等一下! 簡(jiǎn)化嗎? 真? 注釋不應(yīng)該使我的代碼更具可讀性嗎? 此示例具有比實(shí)際代碼更多的注釋。 公平地說,我不包括獲取器和設(shè)置器。 同樣,某些帶注釋的代碼可以更好地壓縮,但這會(huì)使代碼更難閱讀。 當(dāng)然,這是一個(gè)極端的情況。 無論如何,我很高興,因?yàn)槲耀@得了“年度注釋狂”稱號(hào) 。 謝謝盧卡斯!
我們非常依賴注釋,以至于最終濫用它們。 有趣的是,在某些情況下,批注引起了他們打算解決的相同問題。
如果?
讓我們像這樣重寫前面的示例:
電影.java
@MovieEntity @FindAll @LoadWithActors @LoadWithActorsAndAwards public class Movie implements Serializable {@Idprivate Integer id;@Nameprivate String name;@MovieActorsprivate Set<MovieActor> movieActors;@MovieDirectorsprivate Set<MovieDirector> movieDirectors;@MovieAwardsprivate Set<MovieAward> movieAwards; }它肯定看起來更具可讀性。 但是這些注釋不存在。 他們來自哪里?
@LoadWithActors
LoadWithActors.java
@NamedEntityGraph(name = "movieWithActors",attributeNodes = {@NamedAttributeNode("movieActors")} ) public @interface LoadWithActors {}@LoadWithActorsAndAwards
LoadWithActorsAndAwards.java
@NamedEntityGraph(name = "movieWithActorsAndAwards",attributeNodes = {@NamedAttributeNode(value = "movieActors", subgraph = "movieActorsGraph")},subgraphs = {@NamedSubgraph(name = "movieActorsGraph",attributeNodes = {@NamedAttributeNode("movieActorAwards")})} ) public @interface LoadWithActorsAndAwards {}其余的依次類推。 你有感覺。 這個(gè)想法是將注釋元數(shù)據(jù)提取并分組到您自己的自定義注釋中。 然后,您的注釋可以用于表示代碼中所有帶注釋的數(shù)據(jù),從而更易于理解。 就像Java 8 Lambdas一樣,讀起來就像問題聲明一樣。
只是另一個(gè)例子:
WoWBusinessBean.java
@Named @Stateless @TransactionAttribute(TransactionAttributeType.SUPPORTS) @ApplicationPath("/resources") @Path("wowauctions") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public class WoWBusinessBean extends Application implements WoWBusiness {}改寫:
WoWBusinessBean.java
@RestStatelessBean("wowauctions") public class WoWBusinessBean extends Application implements WoWBusiness {}@RestStatelessBean
RestStatelessBean
@Named @Stateless @TransactionAttribute(TransactionAttributeType.SUPPORTS) @ApplicationPath("/resources") @Path("#{path}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public @interface RestStatelessBean {String value() default "#{path}"; }通常,我只編寫一次這些注釋來定義POJO的行為,而不再關(guān)注它們。 如果我可以為所有無狀態(tài)休息服務(wù)重用一個(gè)注釋,那將有多酷?
另一個(gè)不錯(cuò)的效果是,注釋配置元數(shù)據(jù)沒有直接綁定在代碼中。 相反,它被抽象為另一個(gè)注釋。 在這種情況下,有可能在編譯/運(yùn)行時(shí)中覆蓋或替換這些值。
元注釋
我最初是由David Blevins聽說過這個(gè)概念的。 他在“ 元注釋”中寫了一篇關(guān)于這些想法的很好的文章,甚至寫了一個(gè)可能的實(shí)現(xiàn) 。
為注釋繼承,抽象和封裝提供簡(jiǎn)單的Java SE支持會(huì)很方便。 這是所有現(xiàn)有技術(shù)處理注釋方式的重大轉(zhuǎn)變。 只有每個(gè)人都開始支持這種行為才有意義。
有人可能會(huì)問,我們真的需要此功能嗎? 讓我們嘗試權(quán)衡一些利弊:
優(yōu)點(diǎn)
- 簡(jiǎn)化代碼。
- 注釋重用。
- 注釋配置不直接與代碼綁定。 值可以被覆蓋。
缺點(diǎn)
- 另一層抽象。
- 自由地創(chuàng)建自定義注釋可以掩蓋真實(shí)行為。
- 可能會(huì)遇到某種多重繼承陷阱。
結(jié)論
在可預(yù)見的將來,這種元注釋不太可能在Java SE中提供。 在Java 9中,大多數(shù)焦點(diǎn)都放在Jigsaw中。 除了值類型和泛型專業(yè)化之外,關(guān)于Java 10的信息很少。 實(shí)際上,對(duì)于純Java SE,所有這些注釋問題都不是真正的問題。
源文件中存在的批注數(shù)量正成為有關(guān)可讀性和可維護(hù)性的問題。 對(duì)于Java EE和其他類似技術(shù)尤其如此。 考慮一下HTML和CSS。 如果您正在開發(fā)HTML頁(yè)面,而只需要幾個(gè)CSS樣式,則通常將它們內(nèi)聯(lián)到元素中或直接將它們包括在頁(yè)面中。 如果開始使用太多樣式,則可以將它們提取到外部CSS文件中,然后應(yīng)用樣式。 我確實(shí)認(rèn)為必須通過采用元注釋或其他方式來完成某些工作。 你還有其他建議嗎? 請(qǐng)分享!
資源資源
不要忘記查看David Blevins關(guān)于Meta Annotations的帖子。 他的解釋比我更好,包括技術(shù)細(xì)節(jié)。
也是帶有元注釋的JavaOne EJB演示文稿,由David Blevins討論了這些想法。
還有什么比聽大衛(wèi)·布萊文斯本人更好的呢? Java EE 7,無限可擴(kuò)展性遇到無限重用 。
翻譯自: https://www.javacodegeeks.com/2014/12/annotations-annotations-everywhere.html
總結(jié)
以上是生活随笔為你收集整理的注释,无处不在的注释的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 赛尔号单机电脑版(赛尔号单机版V2.0)
- 下一篇: JavaFX技巧15:ListView自