注解的做用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(); } } }