Java注解实际上只是对包、类、方法、成员变量等java程序进行标注。Java注解自身没有业务逻辑,如要实现注解相应的业务逻辑功能必须要由另外的处理类来实现。其基本原理就是通过java反射机制,获取这些java程序的包、类、方法、成员变量的注解,然后加以判断并实现相应的业务功能逻辑。
1.注解出现的背景
以前XML是各大框架的青睐者,它以松耦合的方式完成了框架中几乎所有的配置,但是随着项目越来越庞大,XML的内容也越来越复杂,维护成本变高。
于是就有人提出来一种标记式高耦合的配置方式,即注解。方法、类、字段属性上都可以注解,反正几乎需要配置的地方都可以进行注解。
注解可以提供更大的便捷性,易于维护修改,但耦合度高,而 XML 相对于注解则是相反的。追求低耦合就要抛弃高效率,追求高效率必然会遇到耦合。
2.Java注解应用
在看注解的用途之前,有必要简单的介绍下XML和注解区别,注解:是一种分散式的元数据,与源代码紧绑定;xml:是一种集中式的元数据,与源代码无绑定。
注解的应用包括:一、生成文档,通过代码里标识的元数据生成javadoc文档。二、编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证。三、编译时动态处理,编译时通过代码里标识的元数据动态处理,例如动态生成代码。四、运行时动态处理,运行时通过代码里标识的元数据动态处理,例如使用反射注入实例。
3.Java注解分类
Java注解的分类包括:
一、Java自带的标准注解,包括@Override、@Deprecated、@SuppressWarnings等,使用这些注解后编译器就会进行检查。
二、Java元注解,元注解是用于定义注解的注解,包括@Retention、@Target、@Inherited、@Documented、@Repeatable 等。元注解也是Java自带的标准注解,只不过用于修饰注解,比较特殊。
三、自定义注解,自定义注解用户可以根据自己的需求定义注解。
3.1Java自带的标准注解
JDK 自带的以下标准注解:
@Override:对覆盖超类中的方法进行标注,如果被标注的方法并没有实际覆盖超类中的方法,编译器会发错错误警告。
@Deprecated:对不鼓励使用或已过时的方法进行标注,当开发人员对这些被标注的方法进行调用时,会显示该方法已过时的提示信息。
@SuppressWarnings:选择性的取消特定代码段中的警告。
@FunctionalInterface :用于指示被修饰的接口是函数式接口,在 JDK8 引入。
3.1.1@Override
如果试图使用 @Override 标记一个实际上并没有覆写父类的方法时,java 编译器会告警。
3.1.2Deprecated
@Deprecated 用于标明被修饰的类或类成员、类方法已经废弃、过时,不建议使用。
3.1.3@SuppressWarnings
@SuppressWarnings 用于关闭对类、方法、成员编译时产生的特定警告。
(1)抑制单类型的警告
(2)抑制多类型的警告
(3)抑制所有类型的警告
@SuppressWarnings 注解的常见参数值的简单说明:
@SuppressWarnings(“unchecked”)//执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。
@SuppressWarnings(“unused”) //未使用的变量。
@SuppressWarnings(“resource”) //有泛型未指定类型。
@SuppressWarnings(“path”) //在类路径、源文件路径等中有不存在的路径时的警告。
@SuppressWarnings(“deprecation”) //使用了不赞成使用的类或方法时的警告。
@SuppressWarnings(“fallthrough”) //当 Switch 程序块直接通往下一种情况而没有 break; 时的警告。
@SuppressWarnings(“serial”)//某类实现Serializable(序列化)javadoc注释规范, 但没有定义 serialVersionUID 时的警告。
@SuppressWarnings(“rawtypes”) //没有传递带有泛型的参数。
@SuppressWarnings(“finally”) //任何 finally 子句不能正常完成时的警告。
@SuppressWarnings(“try”) // 没有catch时的警告。
@SuppressWarnings(“all”) //所有类型的警告。
3.1.4@FunctionalInterface
@FunctionalInterface 用于指示被修饰的接口是函数式接口,在 JDK8 引入。
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
3.2Java元注解
元注解是java API提供的,是用于修饰注解的注解,通常用在注解的定义上:
@Retention:用来声明注解的保留策略。
@Targe:标注所修饰的对象范围。
@Inherited:表示注解可以被继承。
@Documented:表示注解应该被JavaDoc工具记录。
@Repeatable:JDK 8 新增的注解,允许一个注解在同一声明类型(类、属性或方法)中多次使用。
3.2.1@Retention
@Retention用来定义该注解在哪一个级别可用,在源代码中(SOURCE)、类文件中(CLASS)或者运行时(RUNTIME)。
@Retention 源码:
RetentionPolicy 是一个枚举类型,它定义了被 @Retention 修饰的注解所支持的保留级别。
RetentionPolicy.SOURCE:源码级注解。注解信息只保留在.java源码中。源码在编译后,注解信息被丢弃,不会保留在.class中。
RetentionPolicy.CLASS:编译时注解。注解信息会保留在.java源码以及.class中。当运行Java程序时,JVM会丢弃该注解信息,不会保留在JVM中。
RetentionPolicy.RUNTIME:运行时注解。当运行Java程序时,JVM也会保留该注解信息,可以通过反射获取该注解信息。
3.2.2@Documented
@Documented:生成文档信息的时候保留注解,对类作辅助说明。
@Documented 示例:
3.2.3@Target
@Target:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
@Target源码:
ElementType 是一个枚举类型,它定义了被 @Target 修饰的注解可以应用的范围:
ElementType.TYPE:声明类、接口或枚举类型。
ElementType.FIELD:声明成员变量。
ElementType.METHOD:声明方法。
ElementType.PARAMETER:声明参数。
ElementType.CONSTRUCTOR:声明构造方法。
ElementType.LOCAL_VARIABLE:声明局部变量。
ElementType.ANNOTATION_TYPE:声明注解类型。
ElementType.PACKAGE:声明包。
ElementType.TYPE_PARAMETER:声明参数类型。
ElementType.TYPE_USE:使用类型。
ElementType.MODULE:声明模块。
3.2.4@Inherited
@Inherited:说明子类可以继承父类中的该注解表示自动继承注解类型。如果注解类型声明中存在 @Inherited 元注解,则注解所修饰类的所有子类都将会继承此注解。
3.2.5@Repeatable
@Repeatable 表示注解可以重复使用。当我们需要重复使用某个注解时,希望利用相同的注解来表现所有的形式时,我们可以借助@Repeatable注解。
以 Spring @Scheduled 为例:
3.3、自定义注解
当我们理解了内置注解, 元注解和获取注解的反射接口后,我们便可以开始自定义注解了。
创建自定义注解和创建一个接口相似,但是注解的interface关键字需要以@符号开头,我们可以为注解声明方法。
自定义注解格式:
这边总共定义了4个注解来演示注解的使用:
(1)定义一个可以注解在Class,interface,enum上的注解。
(2)定义一个可以注解在METHOD上的注解。
(3)定义一个可以注解在FIELD上的注解。
(4)定义一个可以注解在PARAMETER上的注解。
4.使用反射读取注解
目前大部分框架(如Spring、MyBatis、SpringMVC)都使用了注解简化代码并提高编码的效率(使用注解之前使用的xml进行配置)。
ORM,Object-Relationl Mapping,对象关系映射,它的作用是在关系型数据库和对象之间作一个映射,这样我们在具体的操作数据库的时候,只要像平时操作对象一样操作它就可以了,ORM框架会根据映射完成对数据库的操作,就不需要再去和复杂的SQL语句打交道了。常用的ORM框架有MyBatis和Hibernate。
在ORM中,数据库表对应Java实体类,数据库表的字段对应Java实体类的成员变量,数据库表的记录对应Java实体类的对象。
其实ORM可以借助注解来进行映射,并使用反射读取注解信息完成最终的操作。
如下模拟实现MyBatis的注解并使用反射读取。
5.总结
注解做程序的配置是现代软件开发的主流,注解其实是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理可以提供更大的便捷性便于维护修改。
作者简介
▶▶▶
Hello
张群,毕业于河北大学,现任银行转型业务开发部java开发工程师,主要工作方向分布式核心对公cif。
招聘启事
北银金融科技有限责任公司根植于北京银行javadoc注释规范,是一家致力于大数据、人工智能、云计算、区块链、物联网等新技术创新与金融科技应用的科技企业,公司充分发挥北京银行企业文化和技术积淀先天优势,通过对技术、场景、生态的完美融合,输出科技创新产品和技术服务。
现诚邀优秀人才加盟
共享金融科技时代硕果
扫描此二维码
期待您的加入