主要内容
- 1、什么是java注解
- 2、java注解作用
- 3、java注解分类
- 4、使用java内置的注解
- 5、元注解和其他基本注解关系
- 6、如何自定义注解
1、什么是java注解
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。一般作用在类、方法、变量、参数、包等,可以看作给它们打上一个标签,有一定的作用。在 Junit、Struts、Spring 等工具框架中被广泛使用。例如@Override就是一个注解,表明注解的方法是父类中已经声明过的方法,才可以这样标注,否则会出错。
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("....cat eating....");
}
}
定义一个注解的格式是,@interface +注解名,例如java中@Override注解的定义如下。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
2、java注解作用
1)生成文档,通过代码里标识的元数据生成javadoc文档
2)编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证
3)编译动态处理,编译时通过代码里标识的元数据动态处理。
4)运行时动态处理,运行时通过代码里表示的元数据动态处理。
5)代替xml的功能,减少配置,spring中有所体现。
3、java注解分类
java注解是从JDK5.0开始引入的一种注释机制,目前常见的有10个基本注解。在此之前,先了解一下什么是元注解。
元注解:元注解是可以注解在注解上的注解。可以看作最基本的注解。例如:@Target和@Retention为元注解,它们可以注解其他注解,如@Override。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
java常见的有10个基本内置的注解:
5个元注解(@Retention、@Documented、@Target、@Inherited、@Repeatable )
5个其他基本注解(@Override、@Deprecated、@SuppressWarnings、@SafeVarargs、@Functionallnterface);
1)@Override-检查该方法是否是重写方法,如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
2)@Deprecated-标记过时方法,如果使用该方法,会报编译警告。
3)@SuppressWarnings-指示编译器去忽略注解中声明的警告。
4)@SafeVarargs-忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
5)@Functionallnterface-标识一个匿名函数或函数式接口。
6)@Retention-标识这个注解怎么保存,是在代码中,还是在class文件中,或者是在运行时可以通过反射访问。
7)@Documented-标记这些注解是否包含在用户文档中。
8)@Target-标记这个注解可以标注哪种 Java 成员。
9)@Inherited-标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)
10)@Repeatable -标识某注解可以在同一个声明上使用多次。
4、使用java内置的注解
下面举例说明如何使用内置的注解。
1)@Override注解,在子类继承父类的函数时使用。这个使用很常见。
public class Animal {
public void eat(){
System.out.println("....animal eating....");
}
}
在子类中使用该注解,当编码时会检测重写的方法在父类中是否含有来判断正错。
public class Cat extends Animal {
@Override
public void eat() {
super.eat();
System.out.println("....cat eating....");
}
}
2)@Deprecated,当使用该注解标记的方法,会提示这个方法过时。下图中就显示了@Deprecated标识的setName1方法过时。
5、元注解和其他基本注解关系
一、java中其他基本注解也是使用元注解进行定义的。
在学习之间,先了解一下@Target和@Retention这2个元注解。
1)@Target注解源码
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
其中value是ElementType类型的数组。
public enum ElementType {
/**标明该注解可以用于类、接口(包括注解类型)或enum声明*/
TYPE,
/**标明该注解可以用于字段声明,包括enum实例*/
FIELD,
/**标明该注解可以用于方法声明*/
METHOD,
/**标明该注解可以用于参数声明 */
PARAMETER,
/**标明该注解可以用于构造函数声明*/
CONSTRUCTOR,
/**标明该注解可以用于局部变量声明*/
LOCAL_VARIABLE,
/**标明该注解可以用于注解声明*/
ANNOTATION_TYPE,
/**标明该注解可以用于包声明*/
PACKAGE,
/**
*标明该注解可以用于类型参数声明
* @since 1.8
*/
TYPE_PARAMETER,
/**
* 标明该注解可以用于类型使用声明
* @since 1.8
*/
TYPE_USE
}
使用@Target注解标识的注解,可以确定该注解使用在什么上面。使用@Target(ElementType.ANNOTATION_TYPE)标注,有 ElementType枚举类可以知道@Target是一个元注解
2)@Retention注解源码
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
其中value属性为RententionPolicy枚举类
public enum RetentionPolicy {
/**
*注解将被编译器丢弃(该类型的注解信息只能保留在源码里面,源码经过编译后,注解信息会被丢弃,不会保留在编译好的class文件里)
*/
SOURCE,
/**
* 注解在class文件中可用,但会被VM丢弃(该类型的注解信息会保留在源码里和class文件里,在执行的时候,不会加载到虚拟机中)
*/
CLASS,
/**
*注解信息将在运行期(JVM)也保留,因此可以通过反射机制读取注解的信息(源码、class文件和执行的时候都有注解的信息) */
RUNTIME
}
@Retention(RetentionPolicy.RUNTIME)表明注解信息会保留在运行期。
二、例如下面2个例子
1)@ SuppressWarnings注解,是使用@Target和@Retention元注解定义的。
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
该注解(1)可以注解在类、接口、方法、字段、构造器、参数、局部变量上。(2)该注解信息只能保留在源码里面,源码经过编译后,注解信息会被丢弃,不会保留在编译好的class文件里,也不会在JVM中。
2)@Deprecated注解,是由@Documented、@Retention和@Target元注解定义的。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
该注解(1)该注解包含在用户文档中(2)可以注解在构造器、字段、局部变量、、方法、包、参数、类、接口上。(3)该注解信息不仅能保留在源码里面,源码经过编译后,注解信息也会保留在编译好的class文件里,最终在JVM中。
注意:(1)定义 注解 时,@Target 可有可无。若有 @Target,则该 注解 只能用于它所指定的地方;若没有 @Target,则该 Annotation 可以用于任何地方。(2)定义 注解 时,@Retention 可有可无。若没有 @Retention,则默认是 RetentionPolicy.CLASS。
6、如何自定义注解
上面已经分析过元注解和其他注解的关系,自定义注解也是使用元注解进行定义。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AnnotationTest {
}
@AnnotationTest为一个自定义的注解,这个注解可以注解到类的方法上,注解的生命周期将保留在运行期。