说明:看第一遍的时候就和看天书一样,后来这天书也看懂了。
注解相当于一个标记,若程序中加入了注解就等于为程序打上了某种标记,没加则等于没有某种标记,以后Javac编译器开发工具和其他程序可以用反射来了解指定类及各种元素上有无何种标记,然后根据这些标记进行相应的操作,标记可以加载包、类、成员变量、方法、方法的参数、以及局部变量上。
一,常见的注解
@Deprecated
该注解用于注解方法体,表示该方法已经过时
@Override
该注解用于注解方法体,表示该方法为重写父类方法,若被注解的方法没有重写父类方法,则编译器报错
@SuppressWarnings
该注解用于取消元素指定的编译器警告。
示例:
package Test;
@SuppressWarnings("Deprecated")
public class Test {
public static void main(String[] args) throws Exception{
}
@Override
public boolean equals(Object obj){
return false;
}
@Deprecated
public void said(){
System.out.println("你好");
}
}
二,源注解
源注解:
源注解是专门用于给注解类型做注解的。
@Retention
本注解用于确定自定义注解的声明周期。
Java文件生命周期:
Java源文件(.java)-->class文件(.class)-->内存中的字节码
本注解中value值为枚举RetentionPolicy中的元素,对应不同的周期:
SOURCE:注解生命周期到java源文件阶段
CLASS:注解生命周期到class文件阶段(也是默认阶段)
RUNTIME:注解生命周期到字节码阶段
@Target
本注解用于确定自定义注解的使用位置或程序元素的种类
本注解中value值为枚举ElementType中的元素,对应程序中不同元素
ANNOTATION_TYPE 注释类型声明 |
CONSTRUCTOR 构造方法声明 |
FIELD 字段声明(包括枚举常量) |
LOCAL_VARIABLE 局部变量声明 |
METHOD 方法声明 |
PACKAGE 包声明 |
PARAMETER 参数声明 |
TYPE 类、接口(包括注释类型)或枚举声明 |
三,自定义注解
1.注解的简单基本格式:
package Test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyAnnotation {
}
自定义注解时可以为注解添加各种属性:格式与抽象方法格式一样:
package Test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyAnnotation {
//定义注解属性
String color();
}
在定义注解属性的同时,可以为注解定义默认值。格式如下:
package Test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyAnnotation {
//定义注解属性
String color() default "blue";
String value();
}
注解中可以定义的属性种类:
八种基本数据类型
String类型
Class类型
枚举类型
注解类型
前五种类型的数组
package Test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyAnnotation {
//String类型的属性
String color() default "blue";
String value();
//数组类型的属性
int[] arr();
//Class类型的属性
Class<?> cls() default String.class;
//枚举类型的属性
ElementType type() default ElementType.TYPE;
}
四,注解的运用
当为程序的元素添加了一个注解后,我们可以通过反射的方式获取这个注解的各种信息
1.当添加注解时,如果该注解中有属性未被赋予默认值,则必须为这些属性赋值,已被默认赋值的属性可以重新设置值。
package Test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyAnnotation {
String color() default "blue";
String value();
int[] arr();
}
class Annotation{
//使用自定义注解,为属性赋值
@MyAnnotation(color="red",value="1983",arr={11,22,33})
public static void main(String[] args){
}
当一个注解中只有value属性时,添加注解时可以简化:
package Test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyAnnotation {
String value();
}
class Annotation{
//当注解只有value属性时,注解书写可简化
@MyAnnotation("1983")
public static void main(String[] args){
}
}
2.注解信息的获取:
package Test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyAnno {
String color() default "blue";
String value();
int[] arr();
}
//使用自定义注解,为属性赋值
@MyAnno(color="red",value="1983",arr={11,22,33})
class AtTest{
public static void main(String[] args){
//判断指定注解是否在该Class中
if(AtTest.class.isAnnotationPresent(MyAnno.class)){
//获取指定注解的对象
MyAnno anno=(MyAnno)AtTest.class.getAnnotation(MyAnno.class);
//获取注解的属性
System.out.println("color="+anno.color());
System.out.println("value="+anno.value());
}
}
}
运行结果:
color=red
value=1983
五,不同元素获取注解对象的方法
---Constructor:
getAnnotation(Class<T> annotationClass)
---Field:
getAnnotation(Class<T> annotationClass)
---Method:
getAnnotation(Class<T> annotationClass)
---Package
getAnnotation(Class<A> annotationClass)