Java注解的简单记录
什么是注解
注解较多的解释是一种元数据(描述数据的数据),其实相当于一种标签.作用就是用来替代XML配置文件,在后期的很多框架里配置基本以注解的形式存在
注解的定义
注解使用 @interface 关键词进行定义,例如
@interface TestAnnotation {}
注意注解也可以加修饰符,但是只能使用pulbic和abstract
注解的属性
@interface TestAnnotation5 {
String name(); //这就是注解的属性,与常规类属性不同的是需要在属性名后加括号
int id() default 100; //这是为属性设置默认值,如果在使用注解时未对该属性赋值,那么就为默认值
boolean value(); //如果参数的名字为value那么赋值的时候可以不写value=
}
元注解
元注解是一种基本注解,可以使用在注解上.
元注解有
@Retention 保留期
RetentionPolicy.SOURCE, 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视
RetentionPolicy.CLASS, 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中
RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取
@Documented
在生成文档是时候可以将被注解的元素写到javadoc文档中
@Target 可以指定被注解的注解使用的位置
- ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
- ElementType.CONSTRUCTOR 可以给构造方法进行注解
- ElementType.FIELD 可以给属性进行注解
- ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
- ElementType.METHOD 可以给方法进行注解
- ElementType.PACKAGE 可以给一个包进行注解
- ElementType.PARAMETER 可以给一个方法内的参数进行注解
- ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
@Inherited 继承
注解本身是没有继承的.使用**@Inherited** 注解过的注解去注解一个超类father时,如果它的子类son没有被任何注解应用,其继承father的子类son就继承了超类father的注解
@Inherited
@Retention(RetentionPolicy.Source)
@TestAnnotation2 {}
//超类father
@TestAnnotation2
public class Father{}
//子类son继承father,就拥有了father的注解@Retention(RetentionPolicy.Source)
public class Son extends Father {}
@Repeatable 可重复(JDK8新特性)
重复使用注解JDK8之前解决方案
@interface person {
String role();
}
@interface persons {
person[] value();
}
public class TestAnnotation3 {
@persons({@person(role = "singer"), @person(role = "dancer")})
public void action() {
}
}
有了 @Repeatable 之后,增加了可读性
@interface persons {
person[] value(); //规定这个属性的名字必须为value
}
@Repeatable(persons.class) //容器注解
@interface person {
String role();
}
//使用
public void TestAnnotation4 {
@person(role = "singer")
@person(role = "dancer")
public void action() {}
}
Java的内置注解
@Deprecated 废弃
@Override 重写
@SuppressWarnings 压制警告
以下两种目前我搞不太懂
@SafeVarargs 参数安全类型注解
@FunctionalInterface 函数式接口注解
注解的读取
读取注解的内容需要依赖反射了.
### 注意注解的默认保留策略仅仅是RetentionPolicy.CLASS,如果想要在运行时读取注解,那么就需要申明保留策略为RetentionPolicy.RUNTIME
判断是否使用了某个注解的方法
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}
例子:
@Retention(RetentionPolicy.RUNTIME) //注意一定要设置保留策略到RUNTIME,否则运行时注解就没了
public @interface MyAnnotation {
int id();
String name();
}
//使用注解测试
@MyAnnotation(id = 5, name = "zs")
public class Test {
public void main(String args[]) {
//获取要检测是否使用注解的类的Class,这个不仅仅局限于类,而是取决于注解的位置,如果在方法上,则要获取方法,属性上则获取属性调用该方法,依次..
Class clazz = Test.class;
//
boolean status = clazz.isAnnotationPresent(MyAnnotation.class);
System.out.println(status); //输出true
}
}
获取Annotation对象
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}
或
public Annotation[] getAnnotations() {}
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation2 {
int id() default 2;
String value();
}
//测试,以类上的注解为例,当然属性,方法上也适用
@MyAnnotation2("ls")
public class Test2 {
public void main(String[] args) {
Class clazz = Test2.class;
boolean status = clazz.isAnnotationPresent(MyAnnotation2.class);
if(status) {
MyAnnotation2 m2 = (MyAnnotation2) clazz.getDeclaredAnnotation(MyAnnotation2.class);
System.out.println(m2.id()); //输出2
System.out.println(m2.value()); //输出ls
}
}
}