一、注解的作用
注解:说明程序的标签(计算机看)
注释:说明程序的标签(程序员看)
作用:
1、编译检查:在编译阶段检查被标注的代码是否符合注解要求(@override)
2、编写文档:在转换为api时起作用(@author 、@since),自动转换为文字说明
3、代码分析:分析被标注的代码是否正确(通过反射)
二、注解的格式
元注解(标注在注解上的注解)
public @interface name {
属性(即方法)
String value();
}
jdk的内置注解:
作用带代码上的注解,编译阶段:
1、@Override 检查该方法是否是重写方法
2、@SuppressWarnings 压制警告
3、@Deprecated 标记过时方法
作用在注解上的注解(元注解):
1、@Retention 说明该注解在代码的哪个阶段起作用:source(源码阶段)、class、runtime(运行时阶段,一般是这个)
2、@Documented 说明该注解是否在生成的api上显示
3、@Target 说明该注解作用的对象:TYPE(类)、METHON(方法上)、FIELD(成员变量上)
4、@Inherited 说明该注解在父类中使用时,是否可以自动由子类继承
三、注解的本质:
本质是一个继承了Annotation的一个接口
通过对注解的class文件反编译得到以下结果:
public interface com.djn.Annotation.Check extends java.lang.annotation.Annotation {}
四、解析注解(获取注解中的值)
package com.djn.Annotation;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/*
* 定义获取注解值的注解样例
* 1、定义注解AnnotationValueDemo
* 2、定义属性path 和 name
*/
@Retention(RUNTIME)
@Target({ TYPE, METHOD })
public @interface AnnotationValueDemo {
String path();
String name();
}
package com.djn.Annotation;
@AnnotationValueDemo(path="com.djn.Annotation", name="AnnotationValueDemo")
public class AnnotationDemo {
/*
* 获取注解的属性值(解析注解)
* 1、获取使用了@AnnotationValueDemo的类的类对象
* 2、获取注解对象
* 相当于在内存当中生成了注解对象
* public class annotation implements AnnotationValueDemo{
String path(){
return path; //这个值获取(path="com.djn.Annotation", name="AnnotationValueDemo")
}
String name(){
return name;
}
}
* 3、获取属性值
*/
public static void main(String[] args) {
//1、获取使用了@AnnotationValueDemo的类的类对象
Class<AnnotationDemo> class1 = AnnotationDemo.class;
//2、获取注解对象
AnnotationValueDemo annotation = class1.getAnnotation(AnnotationValueDemo.class);
//3、获取属性值
System.out.println("path="+annotation.path());
System.out.println("name="+annotation.name());
}
}
五、自定义注解
注解内定义的属性(方法)的返回值类型有:
基本数据类型
数组类型
枚举类型
自定义一个检查方法是否可以正常运行的注解:
package com.djn.Annotation;
import java.lang.reflect.Method;
public class AnnotationDemo {
public static void main(String[] args) {
//1、获取需要检测的类的类对象
Class class1 = Calculator.class;
//2、获取class对象的方法
Method[] method = class1.getMethods();
//3、遍历method方法,找到用Check注解修饰的方法
for(Method method1 : method) {
if(method1.isAnnotationPresent(Check.class)) {
//运行该方法
try {
method1.invoke(class1.newInstance());
} catch (Exception e) {
//捕获异常,输出
System.out.println("-----------------");
System.out.println(method1.getName()+"方法出现异常");
System.out.println("异常名称:"+e.getCause().getClass().getSimpleName());
System.out.println("异常原因:"+e.getCause().getMessage());
System.out.println("-----------------");
}
}
}
}
}
package com.djn.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
* 自定义一个检查指定类中的方法是否可以正常运行的注解:
*
*/
@Retention(RetentionPolicy.RUNTIME) //运行时起作用
@Target(ElementType.METHOD) //作用于方法
public @interface Check {
}
package com.djn.Annotation;
public class Calculator {
@Check
public void calculate() {
int result = 1*8;
System.out.println("calculate ok");
}
@Check
public void calculate1() {
int result = 1/0;
System.out.println("calculate1 ok");
}
@Check
public void calculate2() {
int result = 1+8;
System.out.println("calculate2 ok");
}
}