Java的注解

**注解是现在的有一种开发方式,一些主流的框架都是有这属于自己的注解,比如Spring,Mybatis,XStream等框架啊**

Java对于注解有着四个根本的注解,我们成为元注解
1、元注解
元注解是指注解的注解。包括 @Retention @Target @Document @Inherited四种。
@Target:注解的作用目标
@Target 用于指明被修饰的注解最终可以作用的目标是谁,也就是指明,你的注解到底是用来修饰方法的?修饰类的?还是用来修饰字段属性的.

//@Target(ElementType.CONSTRUCTOR)//表示当前注解使用在构造方法
//@Target(ElementType.ANNOTATION_TYPE)//允许作用在注解上
//@Target(ElementType.PACKAGE)//表示这个注解可以使用在包上
//@Target(ElementType.FIELD)//表示可以用在属性上
//@Target(ElementType.METHOD)//表示可以作用在方法上
//@Target(ElementType.LOCAL_VARIABLE)//表示可以作用在局部变量里
//@Target(ElementType.PARAMETER)//表示可以作用在方法的形式参数中 也就是(@Auto String str)
public @interface Auto {

}

@Retention:注解的生命周期

//@Retention(RetentionPolicy.SOURCE)//当前注解编译期可见,不会写入 class 文件
//@Retention(RetentionPolicy.RUNTIME)//表示在运行中注解仍然有效,可以通过反射调用
//@Retention(RetentionPolicy.CLASS)//表示当前注解在.class文件中可见
public @interface Auto {
}

@Retention 注解指定了被修饰的注解的生命周期,一种是只能在编译期可见,编译后会被丢弃,一种会被编译器编译进 class 文件中,无论是类或是方法,乃至字段,他们都是有属性表的,而 JAVA 虚拟机也定义了几种注解属性表用于存储注解信息,但是这种可见性不能带到方法区,类加载时会予以丢弃,最后一种则是永久存在的可见性。

@Documented:注解是否应当被包含在 JavaDoc 文档中
@Inherited:是否允许子类继承该注解 加上这个注解的注解类的子类会自动继承这个注解

Javaa官方对于注解的解释在

「java.lang.annotation.Annotation」接口中有这么一句话,用来描述『注解』。
The common interface extended by all annotation types
所有的注解类型都继承自这个普通的接口(Annotation)

为什么这么说呢?我们可以来看一一下JDK内置的Override的注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

Override的本质-就是一个接口然后它继承了Annotation的接口

为什么这么说呢 我们来看一个简单的案例
//这是JDK的Annoation类
package java.lang.annotation;
public interface Annotation {
	Class<? extends Annotation> annotationType();
}
//这是我的类实现了Override
public class UserServiceImpl implements Override {
@Override
 public Class<? extends Annotation> annotationType() {
        return null;
    }
}
当我去实现Override接口时,我们发现我们必须实现一个方法那就是Annoation接口中的方法
所以我们可以间接的证明了所有的注解都是一个实现了Annotation的接口,

一般呢Java给我们提供了多个内置的注解一个是用来压制异常的,一个是用来表示待删除的

1.@Deprecated (jdk1.5更新)
// @Deprecated 表示:某个程序元素(类、方法等)已过时

2 /SuppressWarnings (jdk1.5更新)
// @SuppressWarnings(“rawtypes”) 表示:抑制编译器警告(这里清除)

//@SuppressWarnings("unused")//表示对编译警告进行压制
    //@SuppressWarnings(value={"unchecked", "rawtypes"})//压制多重警告
    //@SuppressWarnings("all")//压制所有警告

3 @SafeVarargs 用在构造方法和静态方法或者最终方法上
从java6到java7, 在java.lang这样一个核心package中, 增加且仅增加了一个新注解@SafeVarargs,
对于可变性参数进行安全检查

//示例
 @SafeVarargs
    public static <T> void aa(T ...a){
        System.out.println(a);
    }
//正因为压制了警告,在方法主体内的数据进行变换的时候,会直接发成异常
官方示例
@SafeVarargs //实际上并不安全!
 static void m(List <String> ... stringLists){ 
   Object [] array = stringLists; 
   List <Integer> tmpList = Arrays.asList(42); 
   array [0] = tmpList; //语义无效,但编译时没有警告
   String s = stringLists [0] .get(0); //哦不,运行时ClassCastException!
 }
导致在运行时出现ClassCastException

@@FunctionalInterface //声明定义一个函数式接口 //函数式接口的约束,这个接口中只有一个抽象方法 被default修饰的方法和被static 修饰的方法可以有实现

@FunctionalInterface
public interface TestFunctionalInterface {
    default void bate(){
        System.out.println("BBB");
    }
    static void sate(){
        System.out.println("1111");
    }
    void save(); //只提供一个抽象无实现方法
}

下面是简单使用

 @PostConstruct//lambda
   public void acv(){
        TestFunctionalInterface b=()->{
            System.out.println("aaa");
        };
    }
    当然直接new 这个接口在里面写实现也是可以的 
在接口中的静态方法可以直接使用
 TestFunctionalInterface.sate();

@PostConstruct
从Java EE 5规范开始,Servlet中增加了两个影响Servlet生命周期的注解(Annotion);@PostConstruct和@PreDestroy。这两个注解被用来修饰一个非静态的void()方法 ,被PostConstruct注解修饰的方法会在调用构造方法和初始化方法之前就去执行,被PreDestroy修饰的方法会在调用销毁方法的之后执行,在Spring中如果对象交给了Spring管理那么这个对象也是可以使用这两个注解的

//以下测试在Spring\中通过IOC的方式实现对象交给Spring创建
 @PostConstruct//初始化之前
 //这个方法在Spring管理的对象中可以抛出异常的,网上其他人说Servlet中
 //被这个注解标记的方法不能抛出异常,我没有试所以就留一下疑问吧!
   public void aa() throws FileNotFoundException {  
         new FileInputStream(new File("D:\\javaWep\\Add-ins\\XMLAddins.dtd"));
       System.out.println("bbb");
   }

 @PostConstruct//在销毁之后执行
   public void aa() throws FileNotFoundException {
        new FileInputStream(new File("D:\\javaWep\\Add-ins\\XMLAddins.dtd"));
       System.out.println("bbb");
   }