元注解:
注解元素可用的类型如下所示:
所有基本类型(int、float、boolean等)
String
Class
enum
Annotation
以上类型的数组
########################################
注解都是 @ 符号开头的
注解可以元数据这个词来描述,即一种描述数据的数据。所以可以说注解就是源代码的元数据
注解的作用:
生成帮助文档。这是最常见的,也是 Java 最早提供的注解。常用的有 @see、@param 和 @return 等;
跟踪代码依赖性,实现替代配置文件功能。比较常见的是 Spring2.5开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量;
在编译时进行格式检查。如把 @Override 注解放在方法前,如果这个方法并不是重写了父类方法,则编译时就能检查出
哪一种注解,本质上都一种数据类型,是一种接口类型
Java 8 为止 Java SE 提供了 11 个内置注解。其中有 5 个是基本注解,它们来自于 java.lang 包。有 6 个是元注解,它们来自于 java.lang.annotation 包,自定义注解会用到元注解。
元注解就是负责注解其他的注解。
基本注解
@Override注解
作用是告诉编译器检查这个方法,保证父类要包含一个被该方法重写的方法,否则就会编译出错。这样可以帮助程序员避免一些低级错误。
@Deprecated
/*用来注解类、接口、成员方法和成员变量等,用于表示某个元素(类、方法等)已过时。当其他程序使用已过时的元素时,编译器将会给出警告。
@Deprecated 注解增加了以下两个属性:
forRemoval:该 boolean 类型的属性指定该 API 在将来是否会被删除。
since:该 String 类型的属性指定该 API 从哪个版本被标记为过时。*/
@Deprecatedpublic classDemo1 {
@DeprecatedprotectedString name;private intage;publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}public intgetAge() {returnage;
}public void setAge(intage) {this.age =age;
}
@OverridepublicString toString() {return "Demo1{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
使用的时候会出现警告:
@SuppressWarnings
被该注解修饰的程序元素(以及该程序元素中的所有子元素)取消显示指定的编译器警告,且会一直作用于该程序元素的所有子元素
主要使用方法:
要用在取消一些编译器产生的警告对代码左侧行列的遮挡,有时候这样会挡住我们断点调试时打的断点
果你确认程序中的警告没有问题,可以不用理会。通常情况下,如果程序中使用没有泛型限制的集合将会引起编译器警告,为了避免这种编译器警告,可以使用 @SuppressWarnings 注解消除这些警告。
注解的使用有以下三种:
抑制单类型的警告:@SuppressWarnings("unchecked")
抑制多类型的警告:@SuppressWarnings("unchecked","rawtypes")
抑制所有类型的警告:@SuppressWarnings("unchecked")
警告关键字:
@SafaVarargs
主要是抑制unchecked警告,和前一个注释差不多
有要注意的地方:
@SafeVarargs注解不适用于非 static 或非 final 声明的方法,对于未声明为 static 或
final 的方法,如果要抑制 unchecked 警告,可以使用 @SuppressWarnings 注解。
@FunctionInterface
注解的作用只是告诉编译器检查这个接口,保证该接口只能包含一个抽象方法,否则就会编译出错。
元注解
@Documented
是一个标记注解,没有成员变量。用 @Documented 注解修饰的注解类会被 JavaDoc 工具提取成文档。
@Target
指定一个注解的使用范围,即被 @Target 修饰的注解可以用在什么地方。@Target 注解有一个成员变量(value)用来设置适用目标,value 是 java.lang.annotation.ElementType 枚举类型的数组
@Retention
描述注解的生命周期,也就是该注解被保留的时间长短
有一个value成员变量:取值可能如下:
SOURCE:在源文件中有效(即源文件保留)
CLASS:在class 文件中有效(即 class保留)
RUNTIME:在运行时有效(即运行时保留)
#############################
生命周期大小排序为 SOURCE< CLASS < RUNTIME,前者能使用的地方后者一定也能使用。
如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;如果要在编译时进行一些
预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS 注解;如果只是做
一些检查性的操作,比如 @Override 和 @SuppressWarnings,则可选用 SOURCE 注解。
@Inherited
标记注解,用来指定该注解可以被继承。使用 @Inherited 注解的 Class 类,表示这个注解可以被用于该 Class 类的子类。就是说如果某个类使用了被 @Inherited 修饰的注解,则其子类将自动具有该注解。
自定义注解:
@Target(ElementType.TYPE)
@Inherited
@Retention(RetentionPolicy.RUNTIME)public@interface MyInherited {
}
@MyInheritedpublic classUserDemo1 {public static voidmain(String[] args) {
System.out.println(UserDemo1.class.getAnnotation(MyInherited.class));
System.out.println(UserDemo2.class.getAnnotation(MyInherited.class));
System.out.println(UserDemo3.class.getAnnotation(MyInherited.class));
}
}classUserDemo2 extends UserDemo1{ }classUserDemo3 extends UserDemo1{ }
结果:
@annotations.MyInherited()
@annotations.MyInherited()
@annotations.MyInherited()
@Repeatable
它允许在相同的程序元素中重复注解,在需要对同一种注解多次使用时,往往需要借助 @Repeatable 注解
自定义注解
/*注解前面访问修饰符有公有和默认
一个源程序可以生命多个注解,但是只能一个公有。且其文件名
和公有注解名字一致
1默认情况下,注解可以在程序的任何地方使用,通常用于修饰类、接口、方法和变量等
2成员变量以无形参的方法形式来声明
3成员变量也可以有访问权限修饰符,但是只能有公有权限和默认权限。*/
public@interface MyInherited {
String name();intage();
}
###没有默认值必须在使用的时候设置默认值
@interface YouInherited{
String name()default "huolala";int age() default 2014;
}
@MyInherited(name="hao",age=90)public static voidshow(){
}
标记注解:没有定义成员变量的注解类型被称为标记注解。这种注解仅利用自身的存在与否来提供信息,如前面介绍的 @Override、@Test 等都是标记注解。
元数据注解:包含成员变量的注解,因为它们可以接受更多的元数据,所以也被称为元数据注解。