9.Java注解(Annotation)

一.系统内置标准注解

1.@Override 是一个标记注解类型,它被用作标注方法。

它说明了被标注的方法重载了父类的方法,起到了断言的作用。如果我们使用了这种Annotation在一个没有覆盖父类方法的方法时,java编译器将以一个编译错误来警示。这个annotaton常常在我们试图覆盖父类方法而确又写错了方法名时发挥威力。使用方法极其简单:在使用此annotation时只要在被修饰的方法前面加上@Override即可。

2.@Deprecated,标记已过时

  同 样Deprecated也是一个标记注解。当一个类型或者类型成员使用@Deprecated修饰的话,编译器将不鼓励使用这个被标注的程序元素。而且这种修饰具有一定的 “延续性”:如果我们在代码中通过继承或者覆盖的方式使用了这个过时的类型或者成员,虽然继承或者覆盖后的类型或者成员并不是被声明为 @Deprecated,但编译器仍然要报警。

  值得注意,@Deprecated这个annotation类型和javadoc中的 @deprecated这个tag是有区别的:前者是java编译器识别的,而后者是被javadoc工具所识别用来生成文档(包含程序成员为什么已经过 时、它应当如何被禁止或者替代的描述)。

  在java5.0,java编译器仍然象其从前版本那样寻找@deprecated这个javadoc tag,并使用它们产生警告信息。但是这种状况将在后续版本中改变,我们应在现在就开始使用@Deprecated来修饰过时的方法而不是 @deprecated javadoc tag。

3.SuppressWarnnings,抑制编译器警告:

  @SuppressWarnings 被用于有选择的关闭编译器对类、方法、成员变量、变量初始化的警告。在java5.0,sun提供的javac编译器为我们提供了-Xlint选项来使编译器对合法的程序代码提出警告,此种警告从某种程度上代表了程序错误。例如当我们使用一个generic collection类而又没有提供它的类型时,编译器将提示出"unchecked warning"的警告。通常当这种情况发生时,我们就需要查找引起警告的代码。如果它真的表示错误,我们就需要纠正它。例如如果警告信息表明我们代码中的switch语句没有覆盖所有可能的case,那么我们就应增加一个默认的case来避免这种警告。
  有时我们无法避免这种警告,例如,我们使用必须和非generic的旧代码交互的generic collection类时,我们不能避免这个unchecked warning。此时@SuppressWarning就要派上用场了,在调用的方法前增加@SuppressWarnings修饰,告诉编译器停止对此方法的警告。
  SuppressWarning不是一个标记注解。它有一个类型为String[]的成员,这个成员的值为被禁止的警告名。对于javac编译器来讲,被-Xlint选项有效的警告 名也同样对@SuppressWarings有效,同时编译器忽略掉无法识别的警告名。 @SuppressWarnings(value={ "rawtypes", "unchecked" })

@SuppressWarnings({ "rawtypes", "unchecked" })

@SuppressWarnings("unused") 

抑制警告的关键字 

  • all to suppress all warnings (抑制所有警告)
  • boxing to suppress warnings relative to boxing/unboxing operations(抑制装箱、拆箱操作时候的警告)
  • cast to suppress warnings relative to cast operations (抑制映射相关的警告)
  • dep-ann to suppress warnings relative to deprecated annotation(抑制启用注释的警告)
  • deprecation to suppress warnings relative to deprecation(抑制过期方法警告)
  • fallthrough to suppress warnings relative to missing breaks in switch statements(抑制确在switch中缺失breaks的警告)
  • finally to suppress warnings relative to finally block that don’t return (抑制finally模块没有返回的警告)
  • hiding to suppress warnings relative to locals that hide variable()
  • incomplete-switch to suppress warnings relative to missing entries in a switch statement (enum case)(忽略没有完整的switch语句)
  • nls to suppress warnings relative to non-nls string literals(忽略非nls格式的字符)
  • null to suppress warnings relative to null analysis(忽略对null的操作)
  • rawtypes to suppress warnings relative to un-specific types when using generics on class params(使用generics时忽略没有指定相应的类型)
  • restriction to suppress warnings relative to usage of discouraged or forbidden references
  • serial to suppress warnings relative to missing serialVersionUID field for a serializable class(忽略在serializable类中没有声明serialVersionUID变量)
  • static-access to suppress warnings relative to incorrect static access(抑制不正确的静态访问方式警告)
  • synthetic-access to suppress warnings relative to unoptimized access from inner classes(抑制子类没有按最优方法访问内部类的警告)
  • unchecked to suppress warnings relative to unchecked operations(抑制没有进行类型检查操作的警告)
  • unqualified-field-access to suppress warnings relative to field access unqualified (抑制没有权限访问的域的警告)
  • unused to suppress warnings relative to unused code  (抑制没被使用过的代码的警告) 

4.@SafeVarargs

参数安全类型注解。它的目的是提醒开发者不要用参数做一些不安全的操作,它的存在会阻止编译器产生 unchecked 这样的警告。它是在 Java 1.7 的版本中加入的。

@SafeVarargs // Not actually safe! 
public static void m(List<String>... stringLists) {
   Object[] array = stringLists; 
   List<Integer> tmpList = Arrays.asList(42); 
  array[0] = tmpList; // Semantically invalid, but compiles without warnings 
  String s = stringLists[0].get(0); // Oh no, ClassCastException at runtime! 
}

上面的代码中,编译阶段不会报错,但是运行时会抛出 ClassCastException 这个异常,所以它虽然告诉开发者要妥善处理,但是开发者自己还是搞砸了。 

Java 官方文档说,未来的版本会授权编译器对这种不安全的操作产生错误警告

5.@FunctionalInterface

函数式接口注解,这个是 Java 1.8 版本引入的新特性。函数式编程很火,所以 Java 8 也及时添加了这个特性。

函数式接口 (Functional Interface) 就是一个具有一个方法的普通接口。

比如

@FunctionalInterface
public interface Runnable {
 /**
 * When an object implementing interface <code>Runnable</code> is used
 * to create a thread, starting the thread causes the object's 
* <code>run</code> method to be called in that separately executing 
* thread. 
* <p> 
* The general contract of the method <code>run</code> is that it may 
* take any action whatsoever. 
* 
*
@see java.lang.Thread#run() */ public abstract void run() }

我们进行线程开发中常用的 Runnable 就是一个典型的函数式接口,上面源码可以看到它就被 @FunctionalInterface 注解。 

可能有人会疑惑,函数式接口标记有什么用,这个原因是函数式接口可以很容易转换为 Lambda 表达式。这是另外的主题了,有兴趣的同学请自己搜索相关知识点学习。

 二.自定义注解

三.注解的提取

参考资料 http://www.cnblogs.com/peida/archive/2013/04/26/3038503.html

http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 

http://blog.csdn.net/briblue/article/details/73824058

原文地址:https://www.cnblogs.com/lukelook/p/9197630.html