对Java注解的三层理解

许多程序设计语言都有自己的独门武功,比如C语言可操作内存空间,PHP代码无需编译,Golang有协程。Java自然也有,比如 "Write Once,Run Anywhere" 能力、纯OO特性、以及(本文的主题)注解。现代Java程序员真的是太喜欢注解了,以至于在使用其他编程语言时,都忍受不了无法使用注解。对啊,为啥其他语言大多都不支持注解呢?或许这个问题该反过来思考:为啥Java会有注解这种神奇的存在呢?

第一层理解:注解是面向编译的行为

注解是Java1.5引入的特性,用来给代码打一些『标记』,编译器在编译时通过这些『标记』来执行特定的编译行为。例如,@Override注解会让编译器检查子类的方法是否在父类中有定义,如果父类未定义,编译器就会报错,从而让Bug在编译阶段就能暴露,如下图所示。除了可以让编译器做一些检查外,注解也可以让编译器生成一些代码,比如Lombok中的注解。

第二层理解:注解作为代码的配置

虽然注解本身是面向编译器的,但在运行期,Java程序可以通过反射读取到注解信息(如下图所示)。也就是说,注解信息(就像xml,propertities文件)可以作为Java程序的输入。认识到这一点,就很容易理解为什么可以使用来代替xml配置了。并且,与XML配置不同,注解是直接配置在代码中,更接近配置目标,能增强程序的内聚性。对于倍受XML配置折磨的Java程序员来说,注解配置真是一剂良药,解救他们于xml配置的水深火热之中。但其实注解这种分散式配置的管理效率不如xml集中式配置高,两者各有优势。许多框架在实现时,对两种配置方式都会支持,比如MyBatis、Dubbo等。

第三层理解:通过注解实现AOP

AOP (Aspect Oriented Programming),面向切面的编程,通过预编译方式和运行期间动态代理实现程序功能统一维护的一种技术。AOP是OOP编程思想的延续,它分离了OOP的各种正交问题,降低了O之间的耦合度。AOP有两种实现方式:① 编译期织入(weaving)字节码实现,典型代表是AspectJ;② 运行期通过动态代理实现,典型代表是Spring AOP。编译期直接生成字节码,具体有更好的性能。注解既能面向编译器,又能在运行期读取,所以不管是编译期还是运行期,都可以利用注解来实现AOP。下图一个基于AspectJ实现AOP的例子,实现对方法的无侵入缓存功能。

总结

注解作为Java语言特有的一项能力,它本身只是对代码的一种『标记』,没有侵入性。编译器通过注解可以执行一些特定的编译行为,如代码校验、生成增强代码。在运行期,注解信息可以通过反射被应用程序读取,所以可以用注解来对程序配置。并且,与xml集中式配置相比,注解方式的配置更接近代码,能提高程序的内聚性。除配置外,通过注解实现AOP也是非常典型的应用场景。

微信扫码关注公众号『互联网工匠』,获取更多优质技术文章。

发布了10 篇原创文章 · 获赞 11 · 访问量 2118

猜你喜欢

转载自blog.csdn.net/Tim_mwt/article/details/104058744
今日推荐