正文
引言: 最近入职了新公司,前期比较忙,公司的项目用到了很多自定义注解,自定义注解由于是公司架构设计的,所以和同事沟通中发现很多小伙伴对注解一知半解,晚上在公司加了会班,发布这篇关于注解的文章,希望有帮助到你
什么是注解?
注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、 接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
注解的作用
注解可以用来说明程序,给计算机解释,并非给开发人员看的,注解也可以用来被其他程序读取
注解的格式
注解格式为"@注解名称",在代码中存在,可以添加一些参数,如下:
@SpringBootApplication
public class SpringBootAdminClientApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAdminClientApplication.class, args);
}
}
可以附加在package,class,method,field等上面,相当于给他们添加了额外的辅助信息,可以通过反射机制编程实现对这些元数据的访问
编写文档:通过代码里标识的注解生成文档【生成文档doc文档】 代码分析:通过代码里标识的注解对代码进行分析【使用反射】 编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【Override】
自定义注解
自定义注解: 注解本质上就是一个接口,该接口默认继承Annotation接口
public interface MyAnno extends java.lang.annotation.Annotation {}
// 空注解
public @interface Mobai{
}
只能使用Java提供的基本数据类型,String可以,Class可以,枚举类,其他暂未测试,包装类不可以.自定义类不可以
public @interface Anno02 {
// 属性
String name();
double price() default 99;
String[] authors();
// Anno01 abc(); // 注解
// WeekDay w();
// Class p();
}
enum WeekDay {
SUN, MON
}
class Person {
}
注解的属性类型以及使用自定义注解
只能包含八种基本数据类型,String可以,注解,枚举,Class,或者以上类型的一堆数组,自定义类不可以
@注解名(属性名=属性值, 属性名=属性值) 需要注意的是:注解的属性可以有默认值,当使用注解时不赋值就使用默认值,赋值就按照赋的值
public @interface MoBai {
// 名字
String name();
// 默认属性
String value() default "框架师";
}
public class AnnactionTest {
@MoBai(name = "墨白",value = "")
public static void main(String[] args) {
}
@Test
public void annTest(){
}
}
自定义注解的特殊情况
当注解只有一个属性,并且属性名是value时,在使用注解时可以省略属性名
public @interface MoBai {
String value();
}
@MoBai("abc")
public class Demo11 {
@MoBai(value = "abc")
public static void main(String[] args) {
}
}
元注解
@Target @Retention 什么是元注解:修饰注解的注解叫做元注解
@Target注解
这个注解默认情况下可以放在任意位置,也可以限制注解放在那些位置 @Target(ElementType.TYPE) 注解只能放在类或者接口上 @Target(ElementType.CONSTRUCTOR) 注解只能放在构造方法上 @Target(ElementType.FIELD) 注解只能放在成员变量上 @Target(ElementType.METHOD) 注解只能放在成员方法上 @Target(ElementType.LOCAL_VARIABLE) 注解只能放在局部变量上 具体可以看一下源码,源码解释的比较详细
@Retention
这个注解默认是存在Class阶段,并且限制了注解存活时间;如下 SOURCE = = = = = = = = = = >>CLASS = = = = = = = = = = = = = >>RUNTIME 源代码阶段(.java) = = = = >>编译 = = = >>.class = = = = = = >>运行
//@Target(ElementType.TYPE) // 注解只能放在类或者接口上
//@Target(ElementType.CONSTRUCTOR) // 注解只能放在构造方法上
//@Target(ElementType.FIELD) // 注解只能放在成员变量上
//@Target(ElementType.METHOD) // 注解只能放在成员方法上
//@Target(ElementType.LOCAL_VARIABLE) // 注解只能放在局部变量上
@Retention(RetentionPolicy.RUNTIME)
public @interface MoBai {
}
@MoBai
public class Demo12 {
@MoBai
private String a;
@MoBai
public Demo12() {
}
@MoBai
public static void main(String[] args) {
@MoBai
int x = 10;
}
}
注解的解析
AnnotatedElement接口中:
Annotation getAnnotation(Class annotationClass) 获取一个注解**
Annotation[] getAnnotations() 获取多个注解
boolean isAnnotationPresent(Class annotationClass) 判断有没有指定的注解
注意: Constructor , Field , Method实现了AnnotatedElement接口
如何解析注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Software:IntelliJ IDEA 2020.1 x64
* Author: MoBai·杰
* [@]Interface:MoBook
* 注解描述: 自定义注解
*/
// 限定方法使用
@Target(ElementType.METHOD)
// 活到运行时候
@Retention(RetentionPolicy.RUNTIME)
public @interface MoBook {
String name();
double price();
String[] authors();
}
/**
* Software:IntelliJ IDEA 2020.1 x64
* Author: MoBai·杰
* ClassName:Book
* 类描述: 书籍类
*/
public class Book {
@MoBook(name = "框架师", price = 25.0, authors = "墨白")
public void sell() {
}
}
public class TestMoBook {
public static void main(String[] args) throws Exception {
// 1.获取Class对象
Class className = Class.forName("com.mobai.annion.Book");
// 2.获取Method对象
Method method = className.getMethod("sell");
// 3.通过method对象获取注解
Annotation[] annotations = method.getAnnotations();
// 4.遍历数组
for (Annotation annotation : annotations) {
System.out.println("annotation = " + annotation);
}
// 3.3 boolean isAnnotationPresent(Class annotationClass)
// 判断有没有指定的注解
boolean b = method.isAnnotationPresent(MoBook.class);
System.out.println(b);
if (b) {
// 3.2 Annotation getAnnotation(Class annotationClass) 获取一个注解
MoBook ann = method.getAnnotation(MoBook.class);
System.out.println(ann.name() + "::" + ann.price() + "::" + Arrays.toString(ann.authors()));
}
}
}