注解

注解

1 注解的概述
注释是给人看的,而注解是给程序看的!
注释是用来替代配置文件的!以前总是要写一些配置文件,例如web.xml?里面要写<servlet>和<servlet-mapping>!谁来读配置文件呢?当然是Tomcat!谁来写配置文件呢?当然是我们来写了!
在Servlet3.0中就可以使用使用注解来代替配置文件,开发者就不用再写配置文件了,而是写注解,然后Tomcat来读取注解。

注解也是类,需要定义了才能使用!
分别在Servlet3.0中有一个注解类为@WebServlet,然后我们就可以在Servlet中使用@WebServlet中使用这个注解了。这个注解就是用来替代<servlet>了。然后Tomcat会通过反射来读取注解中的信息!

2 Java中的注解
Java中的觉注解:
@Overrid:作用在方法上的注解。当方法不是重写父类的方法时会报错;
@Deprecated:作用在方法上。标记该方法为作废方法(已过时);
@SuppressWarnings:作用在方法上,压制警告。

3 定义注解类
定义注解类不能使用class、enum,也不能使用interface,而是使用@interface。
public @interface MyAnn{}


4 使用注解目标
  注解可以作用在:类(接口或枚举)、属性、方法、构造器、包、参数、局部变量
package cn.itcast.annocation;

@MyAnn
public class MyClass {
    @MyAnn
    private int a;
    @MyAnn
    public MyClass() {}
    @MyAnn
    public void fun1() {}
    @MyAnn
    public void fun2(@MyAnn String s) {
        @MyAnn
        int n = 10;
    }
}


5 注解的属性
定义注解时也可以给出属性
public @interface MyAnn {
    String value();
    int value1();
}


其中value就是属性!你可能会说,它是一个方法!没错,它是一个方法,但我们非要称之为属性,因为把它当做属性更加好理解。
当为注解指定属性后,那么在使用注解时就必须要给属性赋值了:
@MyAnn(value1=100,value="hello")
public class MyClass {
}


注解的属性还可以有默认值,在使用注解时就可以不给带有默认值的属性赋值了。但没有给出默认值的属性还是要赋值的。

public @interface MyAnn {
    String value() default "hello world";
    int value1();
}
@MyAnn(value1=100)
public class MyClass {
}


在使用注解时,如果只给名为value的属性赋值,那么可以不给出属性的名称直接给出值。
public @interface MyAnn {
    String value() default "hello world";
    int value1() default 100;
}
@MyAnn()
public class MyClass {
}
@MyAnn(value="hello")
public class MyClass {
}
@MyAnn(value1=200)
public class MyClass {
}
@MyAnn(value="hello",value1=200)
public class MyClass {
}
@MyAnn("hello annocation")
public class MyClass {
}
@MyAnn(300)
public class MyClass {
}
@MyAnn("hello",value1=200)
public class MyClass {
}


注解的属性后面要有一对圆括号,而且圆括号内不能给出东西。就像是无参的方法一样;
注解的属性类型只能是:基本类型、String、Enum、Class、注解类型、以上类型的一维数组类型;
注解的属性可以有默认值,例如:int a() default 100;
数组的属性默认值:int[] arr() default {1,2,3},这里不能使用new int[]{1,2,3}
使用注解时,在给数组属性赋值时的格式:@MyAnn(arr={1,2,3});

6 注解的作用目标
在定义注解时可以限制注解的作用目录!例如让注解只能作用在类和方法上。
这需要使用元注解:@Target。该注解有一个属性value,类型为ElementType[],它是枚举类型。

public @interface Target {
    ElementType[] value();
}
public enum ElementType {
  TYPE,FIELD,METHOD,PARAMETED,CONSTRUCTOR,LOCAL_VARIABLE,ANNOCATION_TYPE,PACKAGE
}


在定义注解时,可以使用@Target注解来限制注解的作用目标:
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnn {
}


这样MyAnn就只能作用在类和方法上的!其中ElementType.TYPE表示类和接口。
@MyAnn()
public class MyClass {
    @MyAnn()
    private int a;
    
    @MyAnn()
    public void fun() {}
}


7 注解的保留策略
注解的保留策略是指,注解是只保留在源代码上,还是保留到class文件上,再或者是类在运行时,可以被类加载器加载到内存中。
如果希望注解被反射,那么注解就要保留到运行时,而不是源代码或类文件上。
指定注解的保留策略需要使用元注解@Retention,它有一个value属性,类型为RetentionPolicy类型,RetentionPolicy是枚举类型:
public @interface Retention {
    RetentionPolicy value();
}
public enum RetentionPolicy {
    SOURCE, CLASS, RUNTIME
}


下面代码是指定注解保留到运行时
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnn {
    String value() default "hello";
    int value1() default 100;
}


8 通过反射读取注解
读取注解需要使用反射来完成
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnn {
    String value() default "hello";
    int value1() default 100;
}
@MyAnn(value="hello world", value1=200)
public class MyClass {
    private int a;
    
    @MyAnn("myMethod")
    public void fun() {}
}
public class Demo1 {
    public static void main(String[] args) throws Exception {
        Class clazz = MyClass.class;
        MyAnn myAnn = (MyAnn) clazz.getAnnotation(MyAnn.class);
        System.out.println(myAnn.value());
        System.out.println(myAnn.value1());
        
        Method method = clazz.getMethod("fun");
        MyAnn myAnn1 = method.getAnnotation(MyAnn.class);
        System.out.println(myAnn1.value());
        System.out.println(myAnn1.value1());
    }
}

原文地址:https://www.cnblogs.com/cyf18/p/14289439.html