1.Annotation是从JDK5.0开始引入的新技术 2.Annotation的作用 : (1)不是程序本身,可以对程序作出解释(这一点和注释(comment)没什么区别) (2)可以被其他程序(比如:编译器等)读取 3.Annotation的格式: 注解是以"@注释名"在代码中存在的,还可以添加一-些参数值,例如:@SuppressWarnings(value="unchecked") 4.Annotation在哪里使用? 可以附加在package , class , method , field 等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问
1.@Override :定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方法声明打算重写超类中的另一个方法声明 2.@Deprecated :定义在java.lang.Deprecated中, 此注释可以用于修辞方法,属性,类,表示不鼓励程序员使用这样的元素, 通常是因为它很危险或者存在更好的选择 3.@SuppressWarnings :定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息 与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数都是已经定义好了的,我们选择性的使用就好了 (1)@SuppressWarngs("all") (2)@SuppressWarnings("unchecked") (3)@SuppressWarnings(value={"unchecked","deprecation"})等等
1.元注解的作用就是负责注解其他注解, Java定义了4个标准的meta- annotation类型,他们被用来提供对其他annotation类型作说明 2.这些类型和它们所支持的类在java.lang.annotation包中可以找到( @Target , @Retention ,@Documented , @Inherited ) (1)@Target :用于描述注解的使用范围(即:被描述的注解可以用在什么地方) (2)@Retention :表示需要在什么级别保存该注释信息,用于描述注解的生命周期(SOURCE < CLASS < RUNTIME(默认)) (3)@Document: 说明该注解将被包含在javadoc中 (4)@Inherited:说明子类可以继承父类中的该注解
1.使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口 2.分析: (1) @ interface用来声明一个注解,格式: public @ interface注解名{定义内容} (2)其中的每一个方法实际上是声明了一个配置参数 (3)方法的名称就是参数的名称 (4)返回值类型就是参数的类型(返回值只能是基本类型,Class , String , enum ) (5)可以通过default来声明参数的默认值 (6)如果只有一个参数成员, 一般参数名为value(可以不用写参数名直接设置) (7)注解元素必须要有值,我们定义注解元素时, 经常使用空字符串,0作为默认值
测试代码:
public class Test01 { @MyAnnotation("芈") public static void test03(){ } } @Target({ElementType.METHOD,ElementType.TYPE})//@Target :用于描述注解的使用范围(即:被描述的注解可以用在什么地方) @Retention(RetentionPolicy.CLASS.RUNTIME)//@Retention :表示需要在什么级别保存该注释信息,用于描述注解的生命周期(SOURCE < CLASS < RUNTIME(默认)) @interface MyAnnotation{//@ interface用来声明一个注解,格式: public @ interface注解名{定义内容} //注解参数: 参数类型 参数名();如果没有default值就必须要给注释赋值;如果只有一个参数时,使用value可以直接赋值 String value() default "芈";//如果默认值为-1,代表不存在,indexOf如果找不到就返回-1 }利用反射获取注解内容步骤:
1.先利用反射获取Class对象
2.使用Class.getAnnotations()获取类上的所有注解内容(如果只想获取注解的值,可以使用Class.getAnnotation(XXX.class)获取特定的注解,然后在获取的注解内容使用.value()即可以获取注解的value值)
3.使用Class.getDeclaredField(“XX”)获取Class对象的特定内容的field对象,然后使用field.getAnnotation(XXX.class),获取到注解的内容
所使用例子:
@Tablemi("mi") class Student2 { @Fieldmi(name = "id", type = "int", length = 10) private int id; @Fieldmi(name = "age", type = "int", length = 3) private int age; @Fieldmi(name = "name", type = "varchar", length = 5) private String name; public Student2() { } public Student2(int id, int age, String name) { this.id = id; this.age = age; this.name = name; } }//并提供get和set方法 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface Tablemi{ String value(); } @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface Fieldmi{ String name(); String type(); int length(); }测试代码:
Class c1 = Class.forName("com.mi.demo01.Student2"); //通过反射获取注解 Annotation[] annotations = c1.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } //获的注解的value值 Tablemi tablemi = (Tablemi)c1.getAnnotation(Tablemi.class); String value = tablemi.value(); System.out.println(value); //获得类指定的注解 Field field = c1.getDeclaredField("id"); Fieldmi fieldmi = field.getAnnotation(Fieldmi.class); System.out.println(fieldmi.name()); System.out.println(fieldmi.type()); System.out.println(fieldmi.length()); //获得类指定的注解 Field field1 = c1.getDeclaredField("name"); Fieldmi fieldmi1 = field1.getAnnotation(Fieldmi.class); System.out.println(fieldmi1.name()); System.out.println(fieldmi1.type()); System.out.println(fieldmi1.length()); //获得类指定的注解 Field field2 = c1.getDeclaredField("age"); Fieldmi fieldmi2 = field2.getAnnotation(Fieldmi.class); System.out.println(fieldmi2.name()); System.out.println(fieldmi2.type()); System.out.println(fieldmi2.length());测试结果: