@Override
@FunctionalInterface
@SuppressWarnings
@SafeVarargs
@Deprecated
首先,我们将深入研究Java中最常用的注解之一:@Override。
一、 @Override
覆盖方法的实现或为抽象方法提供实现的能力是任何面向对象(OO)语言的核心。由于Java是OO语言,具有许多常见的面向对象的抽象机制,所以在非终极超类定义的非最终方法或接口中的任何方法(接口方法不能是最终的)都可以被子类覆盖
二、 @FunctionalInterface
随着JDK 8中lambda表达式的引入,函数式接口在Java中变得越来越流行。这些特殊类型的接口可以用lambda表达式、方法引用或构造函数引用代替。根据@FunctionalInterface文档,函数式接口的定义如下:
一个函数式接口只有一个抽象方法。由于默认方法有一个实现,所以它们不是抽象的。
例如,以下接口被视为函数式接口:
public interface Foo { public int doSomething();}public interface Bar { public int doSomething(); public default int doSomethingElse() { return 1; }}
三、 @SuppressWarnings
警告是所有编译器的重要组成部分,为开发人员提供的反馈——可能危险的行为或在未来的编译器版本中可能会出现的错误。例如,在Java中使用泛型类型而没有其关联的正式泛型参数(称为原始类型)会导致警告,就像使用不推荐使用的代码一样(请参阅下面的@Deprecated部分)。虽然这些警告很重要,但它们可能并不总是适用甚至并不总是正确的。例如,可能会有对不安全的类型转换发生警告的情况,但是基于使用它的上下文,我们可以保证它是安全的。
四、 @SafeVarargs
可变参数在Java中是一种很有用的技术手段,但在与泛型参数一起使用时,它们也可能会导致一些严重的问题。由于泛型在Java中是非特定的,所以具有泛型类型的变量的实际(实现)类型不能在运行时被断定。由于无法做出此判断,因此变量可能会存储非其实际类型的引用到类型,如以下代码片段所示(摘自《Java
Generics FAQs》):
List ln = new ArrayList();ln.add(1);List ls = ln; // unchecked warning String s = ls.get(0); // ClassCastException
在将ln分配给ls后,堆中存在变量ls,该变量具有List的类型,但存储引用到实际为List类型的值。这个无效的引用被称为堆污染。由于直到运行时才能确定此错误,因此它会在编译时显示为警告,并在运行时出现ClassCastException。当泛型参数与可变参数组合时,可能会加剧此问题:
public class Foo { public void doSomething(T... args) { // ... }}
五、 @Deprecated
在开发代码时,有时候代码会变得过时和不应该再被使用。在这些情况下,通常会有个替补的更适合手头的任务,且虽然现存的对过时代码的调用可能会保留,但是所有新的调用都应该使用替换方法。这个过时的代码被称为不推荐使用的代码。在某些紧急情况下,不建议使用的代码可能会被删除,应该在未来的框架或库版本从其代码库中删除弃用的代码之前立即转换为替换代码。
为了支持不推荐使用的代码的文档,Java包含@Deprecated注解,它会将一些构造函数、域、局部变量、方法、软件包、模块、参数或类型标记为已弃用。如果弃用的元素(构造函数,域,局部变量等)被使用了,则编译器发出警告。例如,我们可以创建一个弃用的类并按如下所示使用它:
@Deprecatedpublic class Foo {}Foo foo = new Foo();
如果我们编译此代码(在命名为Main.java的文件中),我们会收到以下警告:
$ javac Main.javaNote: Main.java uses or overrides a deprecated API.Note: Recompile with -Xlint:deprecation for details.
通常,每当使用@Deprecated注解的元素时,都会引发警告,除了用于以下五种情况:
声明本身就被声明为是弃用的(即递归调用)。
声明被注解禁止弃用警告(即@SuppressWarnings(“deprecation”)注解,如上所述,应用于使用弃用元素的上下文。
使用和声明都在同一个最外面的类中(即,如果类调用其本身的弃用方法)。
用在import声明中,该声明导入通常不赞成使用的类型或构件(即,在将已弃用的类导入另一个类时)。
exports或opens指令内