注解全解析
什么是注解?
注解有什么作用?
注解是怎么干活的?
如何自定义注解?
什么是注解
注解即元数据,一种描述数据的数据,可以说注解就是源代码的元数据
Annotation是一种应用于类、方法、参数、变量、构造器及包声明中的特殊修饰符
Annotation不能影响程序代码的运行,无论增加、删除注解,代码都始终如一的执行
-
元数据(metadata),数据的数据
元数据可以用来创建文档,跟踪代码的依赖性,执行编译时格式检查,代替已有的配置文件
元数据以标签的形式存在于Java代码中,描述的信息是类型安全的(内部字段有明确类型)
Annotation类型定义了Annotation的名字、类型成员默认值,一个Annotation类型可以是一个特殊的java接口
注解有什么作用
使用XML描述元数据:XML是为了分离代码和配置而引入,但有时候我们希望使用一些和代码紧耦合的描述
Annotation出现之前,开发人员使用自己的方式定义元数据,如标记interfaces,注释,transient等
Annotation给了一个统一的标准规范,在许多框架中与XML结合使用,平衡两者的利弊
注解是怎么干活的
看源码@Override注解,你可能会疑惑,它什么都没有做,那它是如何检查在父类中有一个同名的函数
强调:Annotation仅仅是元数据,和业务逻辑无关
Annotation并不直接对程序的语法产生作用,但是会提供一些程序之外的数据或者信息,影响工具或者类库对程序的处理或者调用的方式,从而影响程序运行时的行为
元注解
元注解的作用就是负责注解其他注解,meta-annotation类型
-
@Target:用于描述注解的使用范围,即被描述的注解可以用在什么地方
ElementType.TYPE:用于描述类、接口或enum声明
ElementType.FIELD:用于描述实例变量,包括enum常量
ElementType.METHOD:用于描述方法
ElementType.PARAMETER:用于描述参数
ElementType.CONSTRUCTOR:用于描述构造器
ElementType.LOCAL_VARIABLE:用于描述局部变量
ElementType.ANNOTATION_TYPE:用于描述注解类型,另一个注释
ElementType.PACKAGE:用于记录Java文件的package信息
ElementType.TYPE_PARAMETER:可以用在Type的声明前
-
ElementType.TYPE_USE:可以用在所有使用Type的地方
初始化对象:String myString = new @NotNull String();
使用 throws 表达式:public void validateValues() throws @Critical ValidationFailedException{ }
-
@Retention:表示需要在什么级别保存该注释信息,用于描述注解的生命周期,即被描述的注解在什么范围内有效
RetentionPolicy.SOURCE:在编译阶段丢弃,编译之后就不再有任何意义,如@Override@SuppressWarnings
RetentionPolicy.CLASS:在类加载的时候丢弃,在字节码文件的处理中使用,注解默认使用这种方式
RetentionPolicy.RUNTIME:不会丢弃,运行时也保留该注解,可以使用反射机制读取该注解信息,自定义注解通常使用这种方式
@Documented:注解是否包含在JavaDoc中
@Inherited:是一个标记注解,如果使用了该注解修饰的annotation注解的class,会被作用于该class的子类
如何自定义注解
自定义注解:@Todo
package com.adagio.demo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Todo {
public enum Priority{LOW, MEDIUM, HIGH}
public enum Status{STARTED, NOT, NOT_STARTED}
String author() default "Yash";
Priority priority() default Priority.LOW;
Status status() default Status.NOT_STARTED;
}
如果注解只有一个属性,可以直接命名为"value",使用时无需在标明属性名
package com.adagio.demo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
String value();
}
注解元素必须有确定的值,可以在定义注解的默认值中指定,也可以在使用注解时指定
使用反射读取注解信息:BusinessLogic
package com.adagio.demo;
import java.lang.reflect.Method;
public class BusinessLogic {
@Todo(priority = Todo.Priority.MEDIUM, author = "Yashwant", status = Todo.Status.STARTED)
public void incompleteMethod(){
}
@Author("Yashwant")
public void someMethod(){
}
public void readAnnotationInfo(){
Class<BusinessLogic> businessLogicClass = BusinessLogic.class;
for(Method method : businessLogicClass.getMethods()){
Todo todoAnnotation = method.getAnnotation(Todo.class);
if(todoAnnotation != null){
System.out.println("Method Name:" + method.getName());
System.out.println("Author:" + todoAnnotation.author());
System.out.println("Priority:" + todoAnnotation.priority());
System.out.println("Status:" + todoAnnotation.author());
}
}
}
public static void main(String[] args) {
System.out.println("开始读取》》》》");
BusinessLogic b = new BusinessLogic();
b.readAnnotationInfo();
System.out.println("读取结束》》》》");
}
}
注解用例
注解的功能很强大,Spring和Hibernate这些框架在日志和有效性中大量使用了注解功能
注解可以应用在使用标记接口的地方,不同的是标记的接口用来定义完整的类,但你可以为单个方法定义注解,如将一个方法暴露为服务
-
servlet3.0引入的新注解,和servlet安全相关的注解:
HandlesTypes 该注解用来表示一组传递给ServletContainerInitializer的应用类
HttpConstraint 该注解代表所有HTTP方法的应用请求的安全约束
HttpMethodConstraint 指明不同类型请求的安全约束
MultipartConfig 该注解标注在Serblet上,表处理请求MIME类型是multipart/form-data
ServletSecurity 该注解标注在Servlet继承类上,强制该HTTP协议请求遵循安全约束
WebFilter 该注解用来声明一个Servlet过滤器
WebInitParam 该注解用来声明Servlet或是过滤器中的初始化参数,通常配合@WebServlet或 @WebFilter使用
WebListener 该注解为Web应用程序上下文中不同类型的事件声明监听器
WebServlet 该注解用来声明一个Servlet的配置
参考文档:
http://www.importnew.com/1029...
http://www.cnblogs.com/peida/...
http://www.cnblogs.com/peida/...
https://www.ibm.com/developer...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。