一、介绍
java1.5开始引入注解,开始时有三个简单注解。
@Deprecated
// 过时@Override
// 父类重写方法@SuppressWarnings("unused")
//压缩警告,去除警告信息
二、注解的特点
-
每一个注解都有一个对应类
-
注解类不能做业务逻辑
-
解决类本质就是一个标记,可以通过反射获取类的注解
三、自定义注解与使用
两个基本注解
@Retention
元注解去指定注解类的生命周期,其中生命周期有三个,分别对应java程序从编写、编译、运行三个时期@Target
指定注解类可以放在类的什么地方。可以通过ElementType
枚举类的值查看
这样我们可以定义一个最简单的注解
/**
* Retention 元注解指定注解类的生命周期
* RetentionPolicy.SOURCE: 编译后便不存在了
* RetentionPolicy.CLASS: 存在与编译期
* RetentionPolicy.RUNTIME: 将字节码加载到内存后依然存在
*
* Target 注解可以放在哪些成分上
* ElementType.TYPE 放在类上
* ElementType.METHOD 放在方法上
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.ANNOTATION_TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})
public @interface MyAnnotation {
}
但是有个问题,如何去使用。
我们谈到过,注解仅仅是标记。所以使用就是扫描类是否有此注解。
这里要结合一些 java 的反射知识。
@MyAnnotation
public class Test {
public static void main(String[] args) {
//判断类上是否存在注解
System.out.println(Test.class.isAnnotationPresent(MyAnnotation.class));
}
}
我们可以进阶下,为自己的注解定义属性
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.ANNOTATION_TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})
public @interface MyAnnotation {
/**
* 自定义类的基本属性,需要加()
* 后面加default,可以为属性添加默认值
* 含有默认值的注解,可以使用默认值
* 属性类型可以是任何java类型,甚至可以是注解类型
* @return
*/
String color() default "blue";
/**
* 数组类型的
* @return
*/
int[] nums() default {1,2,3};
/**
* 有一点特殊的属性
* 只需要为value一个属性值时,可以简写为 @MyAnnotation("123")
* 简写格式 与 @MyAnnotation(value = "123") 等价
* @return
*/
String value();
}
尝试获取
/**
* 为多个属性赋值可以使用逗号分隔
* @MyAnnotation(value = "123",color = "red")
*/
@MyAnnotation(value = "123",nums = {2,3,4})
public class Test {
public static void main(String[] args) {
/**
* 判断类上是否存在注解
*/
System.out.println(Test.class.isAnnotationPresent(MyAnnotation.class));
//获取注解类的实例
MyAnnotation myAnnotation = Test.class.getAnnotation(MyAnnotation.class);
//获取注解类的属性值
System.out.println(myAnnotation.color());
}
}