Java注解詳解

      網友投稿 663 2025-04-05

      在使用Springboot作為Web敏捷開發的框架之后,Springboot除了自動裝配配置的便捷之外,在很多時候需要基于注解來開發。注解不僅增加了代碼的可讀性,還增加了開發的速度。這篇文章主要講述Java 注解。


      元注解

      元注解用于注解其他注解的。Java 5.0定義了4個標準的元注解,如下:

      @Target

      @Retention

      @Documented

      Inherited

      現在來說說這四個元注解有什么作用。

      @Target

      @Target注解用于聲明注解的作用范圍,例如作用范圍為類、接口、方法等。它的取值以及值所對應的范圍如下:

      CONSTRUCTOR:用于描述構造器

      FIELD:用于描述域

      LOCAL_VARIABLE:用于描述局部變量

      METHOD:用于描述方法

      PACKAGE:用于描述包

      PARAMETER:用于描述參數

      TYPE:用于描述類、接口(包括注解類型) 或enum聲明

      @Retention

      該注解聲明了注解的生命周期,即注解在什么范圍內有效。

      SOURCE:在源文件中有效

      CLASS:在class文件中有效

      RUNTIME:在運行時有效(即運行時保留)

      大多數注解都為RUNTIME

      @Documented

      是一個標記注解,有該注解的注解會在生成 java 文檔中保留。

      @Inherited

      該注解表明子類是有繼承了父類的注解。比如一個注解被該元注解修飾,并且該注解的作用在父類上,那么子類有持有該注解。如果注解沒有被該元注解修飾,則子類不持有父類的注解。

      自定義注解

      在Java開發者,JDK自帶了一些注解,在第三方框架Spring ?帶了大量的注解,這些注解稱為第三方注解。在很多實際開發過程中,我們需要定義自己的注解。那么現在以案例的方式來講解自定義注解。

      在注解中,需要使用四種元注解來聲明注解的作用范圍、生命周期、繼承,是否生成文檔等。另外在注解中也可以有自己的成員變量,如果一個注解沒有成員變量則稱為標記注解。注解的成員變量,只支持原始類型、Class、Enumeration、Annoation。

      現在定義一個@Writer注解,該注解被Retention、Documented、Inherited、Target修飾,表明該注解的作用范圍為類、接口和方法,生命周期為運行時、該注解生成文檔,并且子類可繼承該注解。該注解有2個成員變量,一個為name一個為 age,代碼如下:

      Java注解詳解

      @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Target({ElementType.TYPE,ElementType.METHOD}) public?@interface?Writer?{ ????String?name(); ????int?age(); }

      那么有了該注解,怎么用呢?

      該注解的作用范圍為類、方法,寫一個WriterTest,代碼如下:

      @Writer(name?=?"forezp",?age?=?12) public?class?WriterTest?{ ????@Writer(name?=?"miya",?age?=?10) ????public?void?writeBlog()?{ ????????System.out.println("writing?blog"); ????} ??}

      該類有了這個注解有何用?

      一般來說,用該類修飾的類,需要通過反射來做一下邏輯的開發的工作,可廣泛用于AOP、程序的配置等。現在寫一個方法通過反射來解析該注解:

      public?static?void?main(String[]?args)?throws?ClassNotFoundException?{ ????????Class?c?=?Class.forName("com.forezp.annotation.WriterTest"); ????????if?(c.isAnnotationPresent(Writer.class))?{ ????????????Writer?w?=?(Writer)?c.getAnnotation(Writer.class); ????????????System.out.println("name:"?+?w.name()?+?"???age:"?+?w.age()); ????????} ????????Method[]?methods?=?c.getMethods(); ????????for?(Method?method?:?methods)?{ ????????????if?(method.isAnnotationPresent(Writer.class))?{ ????????????????Writer?w?=?method.getAnnotation(Writer.class); ????????????????System.out.println("name:"?+?w.name()?+?"???age:"?+?w.age()); ????????????} ????????} ????}

      這些代碼基本為反射的內容,因為反射在另一篇文章已經詳細講述過,不再重復,運行該Main方法,控制臺打印出如下內容:

      name:forezp ? age:12

      name:miya ? age:10

      案例實戰

      有了上述的講解,你可能對注解有所了解,但是對注解的具體應用并不是很深刻。現在以一個案例來詳細講述。

      大家都對ORM框架Mybitis都非常的熟悉,在這個框架中用了大量的注解。現在模仿這個框架,通過自定義注解,來解析sql 的查詢語句。實現過程大概如下:

      定義@Table @Colum注解

      定義一個實體User,定義一些基本的字段,并用注解修飾

      用User類new對象,給對象的某些字段賦值

      通過反射和注解來生成sql 的查詢語句

      首先定義個一個Table注解,它的作用范圍為類,代碼如下:

      @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Inherited public?@interface?Table?{ ????String?value()?default?""; }

      定義一個Column注解,作用范圍為字段,代碼如下:

      @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public?@interface?Column?{ ????String?value(); }

      定義一個User類,在該類的加上@Table注解,在具體的字段上 @Column注解,代碼如下:

      @Table("user") public?class?User?{ ????@Column("id") ????private?int?id; ????@Column("name") ????private?String?name; ????@Column("age") ????private?int?age; ????@Column("address") ????private?String?address; ????..//省略getter?setter ???}

      寫一個生成sql語句的類,它是通過反射來獲取表名、字段名,加上判斷實體對象的字段值來生成 查詢的 sql 語句的。代碼如下:

      public?class?GenUserSql?{ ????public?static?void?main(String[]?args)?throws?NoSuchMethodException,?IllegalAccessException,?InvocationTargetException?{ ????????User?u1?=?new?User(); ????????User?u2?=?new?User(); ????????u1.setId(1); ????????u2.setName("forezp"); ????????genSql(u2); ????????genSql(u1); ????} ????private?static?void?genSql(User?user)?throws?NoSuchMethodException,?InvocationTargetException,?IllegalAccessException?{ ????????Class?c?=?user.getClass(); ????????StringBuilder?stringBuilder?=?new?StringBuilder(); ????????stringBuilder.append("select?*?from?"); ????????if?(c.isAnnotationPresent(Table.class))?{ ????????????Table?table?=?(Table)?c.getAnnotation(Table.class); ????????????String?tableName?=?table.value(); ????????????stringBuilder.append(tableName).append("?where?1=1?and?"); ????????} ????????Field[]?fields?=?c.getDeclaredFields(); ????????for?(Field?field?:?fields)?{ ????????????String?columnName; ????????????if?(field.isAnnotationPresent(Column.class))?{ ????????????????Column?column?=?field.getAnnotation(Column.class); ????????????????columnName?=?column.value(); ????????????}?else?{ ????????????????continue; ????????????} ????????????String?fieldName?=?field.getName(); ????????????String?getMethodName?=?"get"?+?fieldName.substring(0,?1).toUpperCase()?+?fieldName.substring(1); ???????????????????????Method?method?=?c.getMethod(getMethodName); ????????????Object?fieldValue?=?method.invoke(user); ????????????if?(fieldValue?==?null?||?((fieldValue?instanceof?Integer)?&&?(Integer)?fieldValue?==?0))?{ ????????????????continue; ????????????} ????????????if?(fieldValue?instanceof?Integer)?{ ????????????????stringBuilder.append(columnName?+?"="?+?fieldValue); ????????????} ????????????if?(fieldValue?instanceof?String)?{ ????????????????stringBuilder.append(columnName?+?"="?+?"'"?+?fieldValue?+?"'"); ????????????} ????????} ????????System.out.println(stringBuilder.toString()); ????} }

      運行程序,控制臺打印如下:

      >

      select * from user where 1=1 and name=’forezp’

      select * from user where 1=1 and id=1

      參考資料

      http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html

      慕課網視頻

      源碼下載

      https://github.com/forezp/java-study

      https://mp.weixin.qq.com/s?__biz=MzAxNjk4ODE4OQ==&mid=2247483922&idx=1&sn=f294e58e159dd702a09ca7d8263b687e&chksm=9bed2360ac9aaa763b4b1923264c797b48ed8ab47ad39e963924c6daf68fd7666ed589e5db20&scene=21#wechat_redirect

      Java

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:怎樣修改wps文檔背景是白色
      下一篇:如何excel中畫斜線 excel表格斜線怎么畫
      相關文章
      丁香五月亚洲综合深深爱| 无码色偷偷亚洲国内自拍| 亚洲人成无码网WWW| 亚洲经典千人经典日产| 国产亚洲中文日本不卡二区| 亚洲人成在线精品| 亚洲狠狠ady亚洲精品大秀| 激情内射亚洲一区二区三区| 久久精品亚洲视频| 亚洲AV无码国产丝袜在线观看| 亚洲精品无码专区在线在线播放| 久久精品国产精品亚洲下载| 久久精品国产亚洲Aⅴ香蕉 | 亚洲国产一级在线观看| 在线观看免费亚洲| 亚洲国产精品不卡毛片a在线| mm1313亚洲精品国产| 亚洲成?Ⅴ人在线观看无码| 亚洲Av无码乱码在线播放| 亚洲国产精品人人做人人爱| 亚洲av无码天堂一区二区三区| 亚洲成片观看四虎永久| 国产国拍亚洲精品福利| 国产成人综合亚洲AV第一页| 亚洲欧洲美洲无码精品VA| 亚洲AV无码成人精品区天堂 | 亚洲综合av一区二区三区| 最新亚洲春色Av无码专区| 亚洲成aⅴ人片久青草影院按摩| heyzo亚洲精品日韩| 亚洲婷婷国产精品电影人久久| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 亚洲精品9999久久久久无码| 亚洲AV无码一区二区一二区| 国产成人亚洲毛片| 亚洲中文字幕无码一久久区| 亚洲乱码中文字幕久久孕妇黑人| 亚洲AV日韩AV天堂久久| 亚洲乱码中文论理电影| 亚洲AV无码一区二区乱子仑| 亚洲精品视频久久久|