第八章《Java高级语法》第10节:注解

时间:2022-12-31 12:02:55

​注解可以被理解为一种特殊的注释。普通注释是添加到代码中的人类语言,它可以提高程序的可读性。当源程序被编译为字节码之后,普通注释都会被去除掉,因为这些注释对代码的执行没有任何影响。因此,普通注释只能对代码的阅读者起到帮助。而注释则不同,注释可以对编译器和虚拟机的工作进行指导,也就是说:如果程序员希望自己的编写的代码被按照某种方式被编译或执行,就可以在代码中加入注解。

注解可以出现在类、方法、属性、参数以及枚举常量的前面,甚至注解前面也可以加注解。Java语言本身自带了很多注解,程序员也可以自己定义注解。本小节中仅讲解Java语言中自带的并且是最常用的注解,而在后面章节中讲解反射技术时会讲解注解的工作原理以及如何自定义注解。​

在Java语言中,所有的注解都以@开头,后面再加上注解的名称。最常用的注解莫过于Override。这个注解只能被添加到方法的前面,表示该方法是重写或实现了父类中的同名方法。子类重写父类的方法其实不需要添加任何注解,那么在这个重写的方法的前面加上Override注解有什么作用呢?请看图8-33。​

第八章《Java高级语法》第10节:注解

图8-33 Override注解作用​

图8-33分为左右两部分,这两部分都是子类Child重写父类Father的method()方法的代码截图。左边这部分代码没有任何语法错误,而右边重写过的method()方法却出现了语法问题。这是因为method()方法上面添加了Override注解,这样就表示这个方法是重写父类的方法,因此编译器就会按重写方法的语法规则来检查这个method()方法。经检查发现子类的method()方法与父类的method()方法参数不同,没有完成对父类method()方法的重写,于是就显示出表示语法错误的红色波浪线。而左边部分,子类的method()方法没有添加Override注解,虽然同样也没有达到重写的目的,但编译器认为子类定义的method()方法与父类的method()方法形成了重载关系,所以没有报错。如果程序员马虎大意,就很有可能不会发现子类根本没有重写父类的method()方法,这样会导致调用方法时出现调用错误的情况。​

从这个例子可以看出,如果程序员希望确保子类一定完成了对父类方法的重写,就可以在重写的方法前面添加Override注解,这样编译器就会按照重写的语法规则对这个方法进行检查。反过来,如果另一个程序员看到某个方法前面添加了Override注解,它也会立刻知道这个方法是重写了父类的同名方法。由此可见:Override注解既能指导编译器的语法检查工作,也能帮助程序员更准确的理解代码。​

下面要介绍的注解叫做SuppressWarnings,它的名称直译过来叫“压制警告”。在对源代码进行检查时,编译器会对某些不合理的或可能出现运行时错误的代码给出提示信息,专业上把这些提示信息称为“警告”。默认情况下,IDEA不会直接在代码中显示警告,而是在编辑器右上角显示出一个黄色小三角,这个小三角就是代码出现警告的标志。当用户单击这个小三角时,下面的警告信息窗口就会打开,并且显示出详细的警告信息,如图8-34所示。​

第八章《Java高级语法》第10节:注解

图8-34 IDEA中的警告信息​

而“压制警告”其实就是指在程序中去除警告信息。如果程序员认定自己已经对这些警告有足够深刻的认识并确保能够避免警告所指出的出错风险,就可以使用SuppressWarnings来压制警告。下面的图8-35展示了使用SuppressWarnings注解压制警告的效果。​

第八章《Java高级语法》第10节:注解

图8-35 用SuppressWarnings注解压制警告​

从图8-35可以看出:把SuppressWarnings注解加到了AnnotationTest类之上,该类中所有警告全部消失。需要注意:除类的上面都可以添加SuppressWarnings注解之外,变量和方法的上面也都可以添加添加SuppressWarnings注解,根据注解位置的不同,压制警告的范围大小也不同。​

此外,在SuppressWarnings注解时,在它的后面还添加了一个参数“unused”。unused意思是“没有使用”,这个参数用来通知SuppressWarnings注解要压制的是变量、方法或类没有被使用而产生的警告信息。除了可以压制程序元素没有被使用的警告信息之外,SuppressWarnings注解还能压制其他各种类型的警告,只需要为SuppressWarnings注解传递不同的参数即可。表8-2展示了可以传递给SuppressWarnings注解的常见参数的名称和作用。​

表8-2 SuppressWarnings常用注解参数作用​

参数名称

参数作用

all

压制所有警告

boxing

压制装箱、拆箱操作时的警告

cast

压制映射相关的警告

dep-ann

压制启用注释的警告

deprecation

压制过期方法警告

fallthrough

压制确在switch中缺失breaks的警告

finally

压制finally模块没有返回的警告

incomplete-switch

压制没有完整的switch语句警告

nls

压制非nls格式的字符警告

null

压制对null的操作警告

rawtypes

压制使用generics时忽略没有指定相应的类型警告

serial

压制在serializable类中没有声明serialVersionUID变量警告

static-access

压制不正确的静态访问方式警告

synthetic-access

压制子类没有按最优方法访问内部类的警告

unchecked

压制没有进行类型检查操作的警告

unqualified-field-access

压制没有权限访问的域的警告

unused

压制没被使用过的程序元素的警告

Java语言是一门不断发展更新的语言,所以很多方法在使用过一段时间之后就会有新的方法出现来代替旧的方法。在这种情况下就需要提示开发者不要再使用那些旧的方法了。那么如何才能告知开发者不要再使用哪些旧的方法呢?Java语言提供了一个叫做Deprecated的注解,这个注解能够提示开发者不要再使用某个方法。下面的图8-36展示了方法添加Deprecated注解的效果。​

第八章《Java高级语法》第10节:注解

8-36 Deprecated注解作用​

图8-36中的method()方法就是就是一个不被提倡使用的旧方法。从图中可以看到,在这个方法上面添加了Deprecated注解后,方法在代码编辑器中的背景颜色会发生改变,而如果程序中仍然调用这个方法,方法的名称上面就会出现删除线以表示这个方法已经不被提倡使用。一般情况下,如果某个方法不被提倡使用,都会推出一个新的方法来代替它,所以我们往往会在给方法添加Deprecated注解时,把推荐使用的新方法名称写到旧方法的文档注释中,这样开发者就能知道应该用哪一个新方法来代替旧方法。​

Java语言本身自带的注解很多,但最常用的就是本小节中提到的这3个,正因为它们的使用频率比较高,所以被放到了java.lang包下。在后面的章节中还会陆续给各位读者介绍其他注解。

除此文字版教程外还有更详细的视频讲解,小伙伴们可以点击这里观看。