全面解析Java注解
概述
Annotation(注解)是JDK1.5及以后版本引入的。它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。
注解是以‘@注解名’在代码中存在的,根据注解参数的个数,我们可以将注解分为:标记注解、单值注解、完整注解三类。它们都不会直接影响到程序的语义,只是作为注解(标识)存在,我们可以通过反射机制编程实现对这些元数据(用来描述数据的数据)的访问。
另外,你可以在编译时选择代码里的注解是否只存在于源代码级,或者它也能在class文件、或者运行时中出现(SOURCE/CLASS/RUNTIME)
Java中的常见注解
JDK中的注解
JDK内置系统注解:
- @Override : 覆盖方法注解。如果你使用改标记,而你继承或实现的方法和接口没有该方法。编译器将会报错。
- @Deprecated : 废止注解。 表示该方法已经废止(过时)。但是仍然可以使用。如果用户使用,则会出现警告,并且会在该方法上画一条横线。
- @SuppressWarnings(“deprecation”):忽略警告。 这条表示忽略方法废止警告
第三方注解
Spring注解:
- @Autowired
- @Service
- @Repository
MyBatis注解:
- @InsertProvider
- @UpdateProvider
- @Options
注解的分类
按照运行机制划分
- 源码注解:注解只在源码中存在,编译成.class文件就不存在了;
- 编译时注解:注解在源码和.class文件中都存在(例:JDK自带注解 @Override);
- 运行时注解:在运行阶段还起作用,甚至会影响运行逻辑的注解;
按照来源来分
- 来自JDK的注解
- 来自第三方的注解(大部分)
- 我们自己定义的注解。
元注解
注解的注解
自定义注解
自定义注解的语法要求:
- 使用@interface关键字定义注解。
- 成员以无参无异常方式声明。
- 可以用default为成员指定一个默认值。
成员类型是受限的,合法的类型包括原始类型及string,class,annotation,enumeration , 一般常用的是基本数据类型+ String
如果注解只有一个成员,则成员必须取名为value(),在使用时可以忽略成员名和复制号(=)
注解类可以没有成员,没有成员的注解称为标识注解
元注解:
- @Target—作用域(constructor(构造方法声明),field(字段声明),local_variable(局部变量声明),method(方法声明),package(包声明),parameter(参数声明),type(类,接口声明))
- @Retention—生命周期(source:只在源码显示,编译时会丢弃。class:编译时会记录到class中,运行时忽略。runtime:运行时存在,可以通过反射读取)
- Inherited—标识注解(允许子类继承)
- Documented—生成Javadoc时会包含注解
解析注解
概念:通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。
- Ps1:RetentionPolicy.RUNTIME时,才能获取到注解,SOURCE和CLASS都获取不到注解。
- Ps2:@Inherited对implements不起作用,对extends起作用(只会继承类上面注解,而不会继承该类方法中的注解)。
- Ps3:instanceof概念:用来判断内存中实际对象A是不是B类型。
一般用来做类的类型判断的:a1,a2继承自A;b继承自B;
a1 instanceof A 返回 true;
a2 instanceof a1 返回 false;
a1 instanceof B 返回 fasle;