以前介绍继承的时候,提到对于子类而言,父类的普通方法能够重写也能够不重写,可是父类的抽象方法是必须重写的,若是不重写,编译器就直接在子类名称那里显示红叉报错。例如,之前演示抽象类用法之时,曾经把Chicken鸡类的call方法改成抽象方法,方法声明代码以下所示:html
// 定义一个抽象的叫唤方法。注意后面没有花括号,而且以分号结尾 abstract public void call();
假若派生自鸡类的公鸡类没有重写call方法,编译器除了红叉报错之外,还会弹出提示“Add unimplemented method”,也就是建议开发者为公鸡类补充实现call方法。按照建议点击提示文字,eclipse会自动在公鸡类中添加如下的默认代码:java
@Override public void call() { // TODO Auto-generated method stub }
注意到新增的call方法上面一行,多出了形如“@Override”的标记,该标记看起来彷佛是多余的,即便把它删掉,编译器也不会报错,程序也能正常运行。莫非“@Override”是另外一种形式的注释?实际上,以@符号开头的标记,它们的真正名称叫作“注解”,跟“注释”仅有一字之差,两者的关系恰如名字那样,既有相同点又有不一样点。相同点为:注解同样带有解释说明的涵义,好比Override翻译成中文就是“重写”的意思,表示标记下方的call方法重写了父类的抽象方法。不一样点为:注释是给人看的,而注解还要给编译器看,编译器扫描到注解@Override,便会去检查父类是否存在注解下方的方法声明,若是不存在或者参数类型对不上,就会提示红叉错误。
除了方法重写注解“@Override”以外,还有一种常见的注解叫“@FunctionalInterface”,翻译成中文即是“函数式接口”,猜的没错,该注解专门用来标记Java8规定的函数式接口。函数式接口是一类特殊的接口形式,它的内部有且仅有一个抽象方法,抽象方法多了不行,再来一个抽象方法的话,接口实例就无法简写为Lambda表达式,也就没法成为“函数式”接口。Java自带的几个函数式接口包括:比较器Comparator、断言接口Predicate、消费接口Consumer、函数接口Function、文件过滤器FileFilter、运行器Runnable等等,查看它们的源码,会发现接口定义的上方无一例外都存在注解“@FunctionalInterface”。例以下面是比较器Comparator的核心定义代码:程序员
//该注解表示如下定义的是函数式接口,有且仅有一个抽象方法声明。 //若是同时声明了多个抽象方法,则编译器在编码阶段就会报错。 @FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); // 此处省略比较器接口的剩余代码定义 }
@FunctionalInterface注解明白无误地告诉编译器,它的下方接口是个函数式接口,请务必检查这个接口定义是否符合函数式接口的要求。编译器根据注解的指示,当即扫描注解下方的接口代码,并仔细统计接口内部的抽象方法个数,假若抽象方法的数量不足一个或者多于一个,编译器都会提示错误“Invalid '@FunctionalInterface' annotation; *** is not a functional interface”,意思是“注解@FunctionalInterface是无效的,由于***不是一个函数式接口”,这样正好提醒开发者检查接口定义是否存在问题。
第三种常见的注解名叫“@Deprecated”,早前介绍日期工具Date的时候,在代码中调用日期实例的getYear、getMonth、getDate等方法,这几个方法的名称中间竟然出现了一条删除线。查看相关日期方法的源码,才发觉它们的定义代码上方耸立着注解“@Deprecated”,该注解的含义是“不同意、已废弃”,原因是Java认为这几个日期方法已通过时了,随时都会从开发包中移除,建议开发者将它们替换成日历工具里的对应方法。尽管目前仍然能够在代码中调用这些过期的方法,可是编译器依旧按照规定在方法名称中间显示删除线,而且还会给出警告“Add @SupressWarnings 'deprecated' to '***'”。这警告说的是建议往***添加注解“@SupressWarnings”(含义为屏蔽警告),从而避免此处的警告提示。正所谓“眼不见心不烦”,那就按照建议在日期方法的调用处通通添加新注解“@SuppressWarnings("deprecation")”,添加完了,果真这些“已过期”的警告都被屏蔽掉了。
注解@SuppressWarnings不只可用来屏蔽“已过期”的警告,还能用来屏蔽其它类型的警告,譬如“未使用”这类警告。上一篇文章演示私有方法的反射调用之时,给Chicken类增长了setName、getName、setSex、getSex四个私有方法,这些方法并未被Chicken类自身所调用,编译器会认为它们是“未使用”的方法,于是在这四个方法的定义处提示警告信息“Remove method '***'”,也就是建议删除某某某方法。若是程序员仍想保留这些方法,又不想看到警告提示,则可在Chicken类上方添加注解“@SuppressWarnings("unused")”,表示屏蔽未使用的警告。添加了@SuppressWarnings注解的鸡类定义代码片断示例以下:安全
//该注解表示屏蔽“未使用”这种警告 @SuppressWarnings("unused") abstract public class Chicken { // 此处省略鸡类的其它代码定义 private void setName(String name) { // 设置名称 this.name = name; } private String getName() { // 获取名称 return this.name; } private void setSex(int sex) { // 设置性别 this.sex = sex; } private int getSex() { // 获取性别 return this.sex; } }
上面的四种注解中,@Override、@Deprecated、@SuppressWarnings这三种是从Java5开始引入的,而@FunctionalInterface是在Java8才引入的。除此以外,Java7还引入了第五种注解名叫“@SafeVarargs”,主要目的是兼容可变参数中的泛型参数,该注解告诉编译器:此处可变参数中的泛型是类型安全的,没必要担忧强制类型转换的问题。因为前述的五种注解是系统提供给开发者使用的,所以它们被统称为“内置注解”。eclipse
更多Java技术文章参见《Java开发笔记(序)章节目录》ide