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");
}