註解的做用java
Java內置註解sql
自定義註解數據庫
使用自定義註解ide
利用反射讀取註解信息orm
註解的英文是Annotation,能夠覺得註釋、註解。可是咱們習慣稱其爲「註解」,由於,他不只有註釋的功能,還有其餘功能。blog
註解不只有「解釋說明(註釋)」的功能,還能被其餘其餘class文件讀取到,讓其餘class進行某些操做。get
package lixin.gan; import java.util.Date; public class InnerAnnotation { /* * Java內置有多個註解,好比@Override, @Suppresswarning, @Deprecated.... * * @Override 表示重寫父類中的同名方法,若是父類中沒有該同名方法,則會提示編譯錯誤 * @SuppressWarnings 能夠設置警告的等級,當所處的類或者方法中出現了對應的警告時,警告會被忽略 * @Deprecated 表示的是不推薦使用 */ @Override public String toString() { return "hello world"; } @Deprecated public void test() { Date d = new Date(); d.getMinutes(); } public void demo1() { int a = 0; } @SuppressWarnings("all") public void demo2() { // 相對於demo1而言,這裏定義了變量a,可是沒有使用,也不會出現警告 int a = 0; } }
要本身定義註解,能夠看一下Java內置的註解是怎麼寫的,以SuppressWarnings爲例:編譯器
package java.lang; import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); }
依葫蘆畫瓢,咱們能夠寫出咱們本身的註解:it
package lixin.gan; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /* * @Target(value={....})是指,該註解能夠在哪些地方使用 */ @Target(value= { ElementType.METHOD, // 方法處 ElementType.TYPE, // 類型處,好比class、interface ElementType.FIELD, // 屬性字段處 ElementType.PACKAGE, // 包名處 ElementType.PARAMETER // 參數的地方 }) /* * @Retention() 代表該註解會保留在哪裏 */ //@Retention(RetentionPolicy.CLASS) 該註解會保留在class文件中 //@Retention(RetentionPolicy.SOURCE) 該註解會保留在源代碼中 // 上面的兩種註解,都是針對編譯器可見的,可是在運行時,註解就失效了 @Retention(RetentionPolicy.RUNTIME) // 註解保留到運行時,能夠保證被其餘類來解析 public @interface MyAnnotation { /** * 定義註解的參數值, 能夠有默認值;沒有默認值時,使用該註解,必須提供值。 */ String name() default ""; // 表示一個名爲name的「屬性」,類型是String int age() default 0; // 表示一個名爲age的「屬性」, 類型是int, 默認值是0 String[] hobby() default {"basketball", "swimming"}; // 類型是String[] String value(); // 對於value來講比較特別,若是一個註解中,只有value沒有默認值,那麼能夠省略value,直接寫值 /* @MyAnnotation(value="hello") 等價於 @MyAnnotation("hello") * */ }
這裏,咱們從新建立兩個註解:MyTable,MyField,分別用來對錶名和屬性進行註解io
package lixin.gan.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(value= {ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface MyTable { String value(); }
package lixin.gan.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(value= {ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface MyField { String columnName(); String type(); int length(); boolean canEmpty() default true; boolean primaryKey() default false; }
使用咱們上面的兩個註解,假設,如今有一個Person類,對應數據庫中的person表,因而,咱們就能夠這樣作了:
package lixin.gan.annotation; @MyTable("Person") // 等價於@Table(value= "Person") public class Person { @MyField(columnName="id", type="int", length=10, primaryKey=true) private int id; @MyField(columnName="name", type="varchar", length=30) private String name; @MyField(columnName="gender", type="String", length=3) private String gender; @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", gender=" + gender + "]"; } }
package lixin.gan.orm; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import lixin.gan.annotation.MyField; import lixin.gan.annotation.MyTable; public class UseReflectionReadAnnotation { public static void main(String[] args) { try { Class clas = Class.forName("lixin.gan.orm.Person"); // 獲取「類」全部的註解 Annotation[] annotations = clas.getAnnotations(); for (Annotation tmp : annotations) { System.out.println(tmp); } // @lixin.gan.orm.annotation.Table(value=Person) // 由於一個地方,可使用多個註解,那麼,能夠經過下面這種方式來查看使用具體某個註解的信息 // 得到該類來講使用某個註解的信息 MyTable t = (MyTable)clas.getAnnotation(MyTable.class); System.out.println(t); // @lixin.gan.orm.annotation.Table(value=Person) System.out.println(t.value()); // Person // 得到屬性的註解,要先得到類的屬性 Field f = clas.getDeclaredField("name"); // 獲取字段 MyField myField = f.getAnnotation(MyField.class); System.out.println(myField.columnName() + " -- " + myField.type() + " -- " + myField.length() + " -- " + myField.canEmpty()); // name -- varchar -- 30 -- true /** * 此時能夠根據上面的信息,拼接sql來建立表 */ } catch (ClassNotFoundException | NoSuchFieldException | SecurityException e) { e.printStackTrace(); } } }