1.什么是注解?
一个注解就是一个标记,一个注解是一个类。
注解相当于一种标记,在程序中加上了注解就等于为程序加上了某种标记。
注解的定义:java用 @interface Annotation{ } 定义一个注解 @Annotation。
注解的用法:注解可以加在类上,加在类的方法、元素上。详见@Target
注解的作用:加了注解之后,JAVAC编译器,开发工具和其他程序可以用反射来了解你的类以及各种元素上有无任何标记,看你有什么标记,就去干相应的事。
2.常见的注解。
@Override,@Deprecated,@SuppressWarnings为常见的3个注解。
@Override 表示重写某个父类的方法
@Deprecated 表示某个类的属性或方法已经过时,不推荐使用
@SuppressWarnings 用来抑制警告
3.特殊的注解:元注解
@Retention 注解可以用来修饰注解,是注解的注解,称之为元注解。
这个注解可以简单的理解为被他修饰的注解的有效期。
@Retention注解有一个value属性,该注解需要和 RetentionPolicy 配合使用。常见形式:@Retention(RetentionPolicy.SOURCE)
RetentionPolicy是一个枚举类型。 有三个值,enum { SOURCE , CLASS, RUNTIME} 。
这三个值代表了注解被保留的阶段:
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.注解会被编译器丢弃,注解只在源代码中生效。
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler 注解会被编译器拷贝到class文件中去,但是运行时不会被虚拟机加载。
* but need not be retained by the VM at run time. This is the default 这是默认的形式。就是如果只写@Retention,后面不写RetentionPolicy的
* behavior. 时候,默认是作为CLASS的。这点写在@Retention源码的注释上。
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and 注解会被拷贝到字节码文件中,并且会被虚拟机在运行时保留。
* retained by the VM at run time, so they may be read reflectively. 所以这些注解可以通过反射来读取。
* <span style="white-space:pre"> </span>RetentionPolicy.RUNTIME 可以让你从JVM中读取Annotation注解的信息,以便在分析程序的时候使用。
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
4.注解验证与实现
4.1定义一个注解 @Nini
package test;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* 定义注解 @Nini ,用RetentionPolicy.RUNTIME修饰;
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Nini {
}
4.2在代码中使用注解
package test;
import java.lang.reflect.Method;
public class NiniTest {
@Nini
public void hello(){
System.out.println("hello world");
}
public static void main(String[] args) throws Exception, SecurityException {
Method method = NiniTest.class.getMethod("hello", null); // 通过反射的形式,在运行时,通过class和方法名(及参数类型)来查找方法
if (method.isAnnotationPresent(Nini.class)) {
// 如果通过反射可以查到method,则为true
System.out.println(method.getAnnotation(Nini.class));
} else {
System.out.println("no Annotation found");
}
}
}
运行结果:@test.Nini()
如果注解使用CLASS或者SOURCE来修饰,则会输出 no Annotation found
5.注解中添加属性
注解本质上也是一个类,所以注解是可以添加属性的。
注解的属性可以是任何合法的类型:String类型,枚举类型,数组类型,Class类型,注解类型(注解做为注解的属性)。
注解的属性可以有默认值,也可以没有默认值。
5.1注解添加属性示例
<span style="font-size:14px;">@Retention(RetentionPolicy.RUNTIME)
public @interface Nini {
String value() default "yaya";
int[] num() default {1,2,3,4};
}
</span>
之后在代码中使用注解的时候,可以写成以下几种形式。
Method method = NiniTest.class.getMethod("hello", null); // 通过反射的形式,在运行时,通过class和方法名(及参数类型)来查找方法
if (method.isAnnotationPresent(Nini.class)) {
// 如果通过反射可以查到method,则为true
Nini nini = method.getAnnotation(Nini.class);
System.out.println(nini.value());
System.out.println(nini.num()[2]);
System.out.println(method.getAnnotation(Nini.class).num()[2]);
} else {
System.out.println("no Annotation found");
}
<span style="font-size:14px;">@Nini("yaya")
public void hello() {
}</span>
则输出结果:
<span style="font-size:14px;">@Nini(value="pop",num={7,8,9,10})
public void hello(){
System.out.println("hello world");
}</span>
则输出结果:
5.2特殊的属性: value