总结:
JDK内置注解
@Override |
@Deprecated |
@SupressWarnings("all") |
元注解
@Target(ElementType.TYPE/METHOD/FIELD) |
@Retention(RetentionPority.RUNTIME/CLASS/SOURCE) |
@Documented |
@Inherited |
方法
作用位置对象.getAnnotation(注解名.class) | 获得注解对象 |
1. 注解的作用
- 编译检查
例如@Override:检查该方法是否是重写的方法
- 编写文档:javadoc
生成javadoc文档步骤:(假设类Calculation)
a. 新建文件夹,将Calculation.java文件放入该文件夹,打开终端,切换到该文件夹下
b. 删除类中的包
javadoc Calculation.java
d. 双击打开生成的index.html文件,即是javadoc文档
- 代码分析
2. JDK内置注解
- @Override:判断方法是不是重写
- @Deprecated:方法过时
- @SupressWarnings("all"):压制警告,参数all表示压制所有警告
3. 自定义注解
- 格式
元注解
public @interface 注解名 { ... }
反编译这个注解:javap 注解名.class
生成的.java文件:public interface 注解名 extends java.lang.annotation.Annotation { }
说明注解的本质是继承了Annotation的接口
- (属性)抽象方法:本质是成员变量
返回值类型要求是以下几种:(不能是void、class等)
基本数据类型,String,枚举enum,注解,以上类型的数组
//枚举定义
public enum MyEnum {
and,sub,mul,div;
}
- 方法添加注解---给注解的属性赋值:
像成员方法一样给属性赋值:属性1="xxx"
规则:
只有一个属性,属性名是value时,value可以省略
数组中只有一个值时,大括号{ } 可以省略
属性给了默认值,就可以不赋值了(没有给默认值就一定要赋值):String name() default "zhangsan" ;
枚举类型赋值举例:=MyEnum.add
注解类型赋值举例:=@注解1
数组类型赋值举例:={ xxx, xxx, xxx}
//注解
//⚠️ 完整注解要加上 元注解
public @interface MyAnnotation {
String name() default "计算";
MyEnum getMethod();
}
//方法添加注解
@MyAnnotation(getMethod = MyEnum.and)
public void testAdd(){
}
4. 元注解:描述注解的注解
- @Target (ElementType.TYPE):注解添加位置
ElementType 枚举
METHOD:注解作用于方法上
TYPE:注解作用于类上
FIELD:注解作用于成员变量上
- @Retention (RetentionPolity.RUNTIME):注解被保留到哪个阶段
RetentionPolity 枚举
SOURCE:源码阶段
CLASS:...class字节码文件中
RUNTIME:......被JVM读取到
- @Documented :是否被抽取到javadoc文档中
- @Inherited :这个注解是否被子类继承
5. 注解解析:获取注解中的值
- 获取注解作用位置对象 Class、Method、Field :
- Class c=类名.class //作用于类
- 获取注解对象:getAnnotation (注解名.class)
注解名 i=作用位置对象.getAnnotation(注解名.class)
本质是在内存中生成了一个注解接口的实现类对象,重写了其中的抽象,方法的赋值称为返回值
//举例
//@MyAnnotation(age=23,getMethod = MyEnum.and)
public class UseAnnotation {
public static void main(String[] args) {
UseAnnotation u=new UseAnnotation();
u.fun1();
}
@MyAnnotation(age=23,getMethod = MyEnum.and)
public void fun1(){
//获取注解定义位置的对象(Class、Method、Field)
Class<UseAnnotation> c=UseAnnotation.class;
// MyAnnotation annotation = c.getAnnotation(MyAnnotation.class); //作用于类时
try {
Method m = c.getMethod("fun1");
MyAnnotation annotation = m.getAnnotation(MyAnnotation.class); //作用于方法时
int age = annotation.age();
System.out.println(age);
} catch (Exception e){
e.printStackTrace();
}
}
}
- 获取注解中的抽象方法的值:
m.方法名()
本质就是调用实现类中重写的该方法
- 补充:
判断方法是否被某个注解修饰:method.isAnnotationPresent(注解名.class)
//例子
//注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
int age();
String name() default "计算";
MyEnum getMethod();
}
//获取注解中的值
@MyAnnotation(age=23,getMethod = MyEnum.and)
public class UseAnnotation {
public static void main(String[] args) {
UseAnnotation u=new UseAnnotation();
u.fun1();
}
public void fun1(){
Class<UseAnnotation> c=UseAnnotation.class;
MyAnnotation annotation = c.getAnnotation(MyAnnotation.class);
int age=annotation.age();
System.out.println(age);
}
}