Java注解 又称Java标注,是Java语言5.0版本开始支持加入源代码的特殊语法元数据。
Java语言中的类、方法、变量、参数和包等都可以被标注。Java标注和Javadoc不同,标注有自反性。在编译器生成类文件时,标注可以被嵌入到字节码中,由Java虚拟机执行时获取到标注[。
我们在平常编写代码的时候就用到了几个常用的系统注解 @Override @Deprecated SuppressWarnnings
Annotation 注解 就是Java提供了一种元程序中的元素关联任何信息和着任何元数据(metadata)的途径和方法。
Annotation 不能影响程序代码的执行,无论增加、删除 Annotation,代码都始终如一执行
注解的分类:
根据注解参数的个数分类
- 标记注解:没有成员的注解称为标记注解,通过是否存在该注解可以获得相关信息,比如最熟悉的 @Override 注解
- 单值注解
- 完整注解
根据注解使用方法和用途分类
- JDK 内置系统注解
- 元注解 用来修饰注解的注解
- 自定义注解
系统注解
@Override
限定重写父类方法,,它被用作标注方法。它说明了被标注的方法重载了父类的方法,如果注解的方法没有重写父类方法,则会在编译时报错
@Deprecated
标记已过时,如果用此注解修饰的元素,编译器将不鼓励使用该注解
SuppressWarnnings
抑制编译器警告,被用于有选择的关闭编译器对类、方法、成员变量、变量初始化的警告
常见参数值:
- deprecation:使用了不赞成使用的类或方法时的警告;
- unchecked:执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型;
- fallthrough:当 Switch 程序块直接通往下一种情况而没有 Break 时的警告;
- path:在类路径、源文件路径等中有不存在的路径时的警告;
- serial:当在可序列化的类上缺少 serialVersionUID 定义时的警告;
- finally:任何 finally 子句不能正常完成时的警告;
- all:关于以上所有情况的警告。
用例:
class Student
{
@SuppressWarnings(value = {"rawtype","unchecked"})
void print1(){
}
@SuppressWarnings( {"rawtype","unchecked"})
void print2(){
}
@SuppressWarnings("unused")
void print3(){
}
}
元注解:
元注解的作用就是用来注解其它注解,主要有四种元注解
- @Target,
- @Retention,
- @Documented,
- @Inherited
@Target:
注明了注解修饰的对象的类型:
取值(枚举类型 ElementType)有:
- CONSTRUCTOR: 修饰构造器
- FIELD:修饰域
- LOCAL_VARIABLE:修饰局部变量
- METHOD:修饰方法
- PACKAGE:修饰包
- PARAMETER:修饰参数
- TYPE:修饰类、接口(包括注解类型) 或enum声明
@Target(ElementType.TYPE)
public @interface MyAnnonation {
}
@MyAnnonation
class Aa{
}
@Retention:
@Retention 定义了该Annotation被保留的时间长短
取值(RetentionPoicy)有:
- SOURCE: 源文件有效
- CLASS: class文件中有效
- RUNTIME: 运行时有效
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnonation {
}
class Aa{
@MyAnnonation
String name;
}
@Documented:
用于描述其它类型的Annotation应该被作为被标注的程序成员的公共API
@Inherited
阐述了某个被标注的类型是被继承的。
如果一个使用了 @Inherited 修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。
1.如果子类继承父类,并且重写了父类中的带有注解的方法,那么父类方法上的注解是不会被子类继承的。
2.如果子类继承父类,但是没有重写父类中带有注解的方法,那么父类方法上的注解会被子类继承,就是说在子类中可以得到父类方法上的注解。
即使在注解中没有 @Inherited 也会满足上面情况,但是如果该注解是用来修饰类的,则不满足。
自定义注解
使用 @interface 自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。
@interface 用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
定义注解格式:
public @interface 注解名 {定义体}
注解参数的可支持数据类型:
- 所有基本数据类型(int,float,boolean,byte,double,char,long,short)
- String类型
- Class类型
- enum类型
- Annotation类型
- 以上所有类型的数组
对于注解中的参数,只能用public或默认(default)这两个访问权修饰.例如,String value();如果只有一个参数成员,最好把参数名称设为"value",
注解默认值
注解元素必须有确定的值,要么在定义注解的默认值中指定,要么在使用注解时指定,非基本类型的注解元素的值不可为null。
获得注解值
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface MyTypeAnnonation{
String value()default "no";
}
@MyTypeAnnonation(value = "my")
class Fruit
{
}
public class Demo {
public static void main(String []args){
Class cl=Fruit.class;
Annotation annotations[]=cl.getAnnotations();
for(Annotation i:annotations){
if(i instanceof MyTypeAnnonation){
MyTypeAnnonation annonation=(MyTypeAnnonation)i;
System.out.println(annonation.value());
}
}
Annotation annotation=cl.getAnnotation(MyTypeAnnonation.class);
MyTypeAnnonation myTypeAnnonation=(MyTypeAnnonation)annotation;
System.out.println(myTypeAnnonation.value());
}
}
网友评论