1.定义
java提供了一种源程序中的元素关联任何信息和任何元数据的途径和方法。
注解(Annotation),也称元数据, 是jdk1.5以后引入的。
2.注解分类
按照来源分为
2.1 jdk自带的注解
@Override 标识注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }
@Deprecation 注解的程序标识不鼓励程序员使用,已经被抛弃
/** * A program element annotated @Deprecated is one that programmers * are discouraged from using, typically because it is dangerous, * or because a better alternative exists. Compilers warn when a * deprecated program element is used or overridden in non-deprecated code. * */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE}) public @interface Deprecated { }
@SuppressWarnings 压制警告
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { /** * The set of warnings that are to be suppressed by the compiler in the * annotated element. Duplicate names are permitted. The second and * successive occurrences of a name are ignored. The presence of * unrecognized warning names is <i>not</i> an error: Compilers must * ignore any warning names they do not recognize. They are, however, * free to emit a warning if an annotation contains an unrecognized * warning name. * * <p> The string {@code "unchecked"} is used to suppress * unchecked warnings. Compiler vendors should document the * additional warning names they support in conjunction with this * annotation type. They are encouraged to cooperate to ensure * that the same names work across multiple compilers. * @return the set of warnings to be suppressed */ String[] value(); }
2.2 第三方注解 例如spring框架提供的 @Controller @Service @Autoweird等
2.3 自定义注解
按照运行机制可以分为 源码注解 编译时注解 运行时注解
还有一类注解为元注解,是用来给注解进行注解的注解,我们可以用元注解去定义自己的注解
元注解(4个)
@Target({ElementType.METHOD})
注解作用目标
public enum ElementType { Type标识可以作用类,接口,或者枚举 /** Class, interface (including annotation type), or enum declaration */ TYPE, 字段申明,包括枚举的常量 /** Field declaration (includes enum constants) */ FIELD, 方法 /** Method declaration */ METHOD, 参数 /** Formal parameter declaration */ PARAMETER, 构造器 /** Constructor declaration */ CONSTRUCTOR, 局部变量 /** Local variable declaration */ LOCAL_VARIABLE, 注解类型 /** Annotation type declaration */ ANNOTATION_TYPE, 包 /** Package declaration */ PACKAGE, /** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * * @since 1.8 */ TYPE_USE }
@Retention(REtentionPolicy.RUNTIME)
注解的作用区域
public enum RetentionPolicy { 源码 /** * Annotations are to be discarded by the compiler */ SOURCE, 编译的.class文件中还起作业 /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, 运行时候也起作用 /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME }
@Inherited 属于表示注解,标记以后可以被子类继承
@Documented 再生成javaDoc的时候是否包含注解相关申明
如何自定义注解
自定义的语法要求
1.成员参数以无参无异常的方式申明
2.成员类型 包含基本数据类型以及 String Class Annotation Enumeration,
3.注解只有一个成员时候,则成员必须为value()
手写一个自定义注解
package aa.bb.ee.demo;
import java.lang.annotation.*;
@Inherited
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnno {
String value();
int age() default 18;
}
java通过反射机制去解析运行时注解(注意只有@Retention(RetentionPolicy.RUNTIME))时候才能通过反射机制去解析。
package aa.bb.ee..demo;
import java.lang.reflect.Method;
@CustomAnno("类东东")
public class Demo {
@CustomAnno("方法东东")
public void getDog(){
}
public static void main(String[] args) {
try {
//加载类
Class c = Class.forName("aa.bb.ee.demo.Demo");
//解析类上的注解
boolean b = c.isAnnotationPresent(CustomAnno.class);
if(b){
CustomAnno annotation = (CustomAnno) c.getAnnotation(CustomAnno.class);
System.out.println("+++");
System.out.println(annotation.value());
System.out.println("---");
}
//解析方法中的注解
Method[] methods = c.getMethods();
for (Method method : methods) {
boolean annotationPresent = method.isAnnotationPresent(CustomAnno.class);
if (annotationPresent) {
CustomAnno annotation = method.getAnnotation(CustomAnno.class);
System.out.println(annotation.value());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
运行结果如下
+++
类东东
---
方法东东