Java注解(Annotation)
作者:互联网
目录
2.3 @SuppressWarnings(value = "unchecked") 【 压制编辑器警告】
3.2 @Target【标记这个注解应该是哪种Java 成员】
3.3 @Inherited【标记这个注解是继承于哪个注解类 】
3.4 @Documented【 标记这些注解是否包含在用户文档中】
1、前言
大家好,今天这篇博客是带大家简单了解一下 Java注解,让我们赶紧开始今天的旅程吧。
注解相关类都包含在java.lang.annotation包中。
2、JDK基本注解
2.1 @Override【重写】
检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
如果你使用MVC做为项目框架,在service层应该会经常看到。
2.2 @Deprecated【已过时 】
标记过时方法。
已过时的方法会一条横线,我们把鼠标放上去,按住Ctrl点进去。
这里就会发现它在这个方法上使用了@Deprecated这个注解。
2.3 @SuppressWarnings(value = "unchecked") 【 压制编辑器警告】
指示编译器去忽略注解中声明的警告。
这个如果你有强迫症,对你的代码容不得一点"黄色",就可以使用这个注解。
我们现在加上这个注解。
3、JDK元注解【作用在其他注解的注解 】
3.1 @Retention【定义注解的保留策略】
标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
3.1.1 Retention(RetentionPolicy.SOURCE)【一般情况下用不到】
简介: 注解仅存在于源码中,在class字节码文件中不包含。
3.1.2 @Retention(RetentionPolicy.CLASS)【如果括号里面上面什么都不写,默认】
简介: 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得。
3.1.3 @Retention(RetentionPolicy.RUNTIME)【用的最多!!!】
简介:注解会在class字节码文件中存在,在运行时可以通过反射获取到。
举例:这里我打开一个Controller。
这个Controller上用了一个@RestController的注解,我们把鼠标放上去,按住Ctrl点进去。
这上面的注解都是Java元注解。而这里面正好用到了@Retention(RetentionPolicy.RUNTIME)。
3.2 @Target【标记这个注解应该是哪种Java 成员】
指定被修饰的Annotation可以放置的位置(被修饰的目标)。
注:可以指定多个位置,例如:@Target({ElementType.METHOD, ElementType.TYPE}),也就是此注解可以在方法和类上面使用。
3.2.1 @Target(ElementType.TYPE) 【接口、类 (包括注释类型)或枚举声明 】
3.2.2 @Target(ElementType.FIELD)【字段声明(包括枚举常量)* 】
3.2.3 @Target(ElementType.METHOD) 【方法声明 】
3.2.4 @Target(ElementType.PARAMETER) 【方法参数声明】
3.2.5 @Target(ElementType.CONSTRUCTOR) 【构造函数声明】
3.2.5 @Target(ElementType.LOCAL_VARIABLE) 【局部变量声明】
3.2.6 @Target(ElementType.ANNOTATION_TYPE)【 注释类型声明 】
3.2.7 @Target(ElementType.PACKAGE) 【 包声明 】
举例:还是上面Controller用的@RestController
它这里使用@Target(ElementType.TYPE),我们来试试看能不能作用在其他的地方。
在这里我们发现,它作用于属性和方法上都报错了,所以它真的只能作用于接口或类上!大家如果有兴趣现在可以把自己用过的注解一个一个点进去看看。
3.3 @Inherited【标记这个注解是继承于哪个注解类 】
指定被修饰的Annotation将具有继承性 【默认 注解并没有继承于任何子类】
举例:以@Transactional这个注解为例
我们点进去看看。
我们就可以看到@Inherited这个注解,只要带有@Inherited这个元注解,说明@Transactional这个注解有继承性。
假如A这个接口使用了@Transactional这个注解,因为@Transactional这个注解上使用@Inherited这个注解,那B这个实现类去实现A这个接口,那B实现的所有方法里面都有事务,这就是继承性。
3.4 @Documented【 标记这些注解是否包含在用户文档中】
指定被修饰的该Annotation可以被javadoc工具提取成文档。
4、自定义注解
自定义注解,顾名思义就是我们自己定义的注解。
像@RestController,@GetMapping等等,这些都是第三方框架提供给我们的注解,它们都是自定义的注解。
举例:
这上面就是一个自定义的注解,是不是感觉挺简单的,接下来我们来打开一个Demo。
我们在这个@MyAnnotation1自定义注解上使用了@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD}),所以它能同时作用于类和属性上。
而且我们看到了括号里有我们在注解里声明的属性name,如果我们将其省略,只写值。
我们会发现它报错了,但有一种情况下,它不会报错,就是我们把属性名改成value。
当然,这个前提条件是你只输入一个属性的值。如果有多个属性的值,他还是会报错的。
小结:
只有名字为“value”属性,赋值时可以省略属性名。
使用@interface关键字, 其定义过程与定义接口非常类似, 需要注意的是: Annotation的成员变量在Annotation定义中是以无参的方法形式来声明的, 其方法名和返回值类型定义了该成员变量的名字和类型, 而且我们还可以使用default关键字为这个成员变量设定默认值。
例如:
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Tag {
String name() default "该叫啥才好呢?";
String description() default "这家伙很懒, 啥也没留下...";
}
5、注解分类
根据Annotation是否包含成员变量,可以把Annotation分为两类:
5.1 标记Annotation
没有成员变量的Annotation; 这种Annotation仅利用自身的存在与否来提供信息。
5.2 元数据Annotation
包含成员变量的Annotation; 它们可以接受(和提供)更多的元数据。
6、提取Annotation信息
使用AnnotatedElement接口中的方法提取注解中的数据。
例如:
Class/Constructor/Field/Method/Package这些类都实现了AnnotatedElement接口。
注:只有当定义Annotation时使用了@Retention(RetentionPolicy.RUNTIME)修饰,JVM才会在装载class文件时提取保存在class文件中的Annotation,该Annotation才会在运行时可见,这样我们才能够解析。
举例:
我们打开一个测试类,实验一下。
在上面我们说了class实现了AnnotatedElement接口,而AnnotatedElement有一个getAnnotation的方法,我们调用,最后得到一个注解对象annotation,我们再用annotation去点name这个属性,打印。
标签:Java,Target,3.2,注解,ElementType,Annotation,Retention 来源: https://blog.csdn.net/weixin_53041251/article/details/122341138