Java注解
Java注解,从jdk1.5(@since 1.5)开始,java增加注解的概念,从而也开始了注解开发,尤其在Spring各种框架中,更是将注解运用到极致,如今Java开发已离不开注解。我们常见和使用注解如:@Override(重写方法)@NotNull(不能为空)@Deprecated(被废弃的类、方法等)@SuppressWarnings(压制警告)@RestController(用于spring的controller类)@Service(spring的service层)@Autowired(注入属性)@Value(获取application.yml中属性值)…。
1. Java注解和注释
类似之处:都是标注并解释意思;
不同之处:
- 注释对程序没有影响,注解对程序有影响;
- 注释对程序员解释类、方法和属性等是什么意思,注解对程序解释类、方法、属性等是什么意思;
- 注解可以提高程序开发效率,特别是Spring、Spring boot、Spring Cloud框架之下。
Java注解和反射结合,才能发挥更大优势
2.Java元注解
Java中存在6种元注解,一般用在注解类上,用于解释注解的注解,包含:Documented、Target、Retention、Inherited、Native和Repeatable,都是java.lang.annotation包下的,其中前四个元注解是jdk1.5提供的,后两个是jdk1.8提供的。
6种元注解意思:
- @Documented表示是否将注解生成在Javadoc中
- @Target表示注解可以用在哪些位置
- @Retention表示注解在哪些位置有效
- @Inherited表示子类可以继承父类注解
- @Native表示可以生成本机头文件
- @Repeatable表示该注解类型是可重复的
6种元注解源码:
//Documented 没有属性
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
/*
Target 有一个属性value,属性类型为ElementType[]数组。
注意:
1.value()不是方法,是属性;
2.只有属性value在使用时可以省略,例如value = {""},可以直接使用{""},如果是name,必须name = {""}。
ElementType是一个元素类型的枚举:
TYPE类,FIELD属性,METHOD方法,PARAMETER参数,CONSTRUCTOR构造方法,LOCAL_VARIABLE本地变量,ANNOTATION_TYPE注解类型,PACKAGE包,TYPE_PARAMETER,TYPE_USE,后两种是jdk1.8提供,以上枚举表示注解可以在类、方法、属性等其他位置可以使用。
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
/*
Retention 有一个属性value,类型为RetentionPolicy
RetentionPolicy是注解有效位置的枚举:
SOURCE源代码时候有效;
CLASS类被编译有效,即Class文件;
RUNTIME编译和jvm运行时有效,因此在运行时可以通过反射获取Class文件,进行动态编程。
范围区间排序:RUNTIME > CLASS > SOURCE。
我们一般自定义注解都使用RUNTIME。
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
//Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
//Native
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface Native {
}
/*
Repeatable 有一个属性value,类型为Class<? extends Annotation> 。
类型是一个Class类,同时继承自Annotation。
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
/**
* Indicates the <em>containing annotation type</em> for the
* repeatable annotation type.
* @return the containing annotation type
*/
Class<? extends Annotation> value();
}
3.自定义Java注解
通过上述对元注解的了解,我们可以根据元注解自定义一个Java注解,注解的类型是@interface,如下:
@Documented
@Target(value = {ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
String[] value() default {};
String name() default "";
int id() default 0;
Class<? extends Annotation> annotation() default Annotation.class;
Class<?>[] scanBasePackageClasses() default {};
}
注意:自定义注解中,属性都添加default默认值,因此我们在使用注解时不赋值也不会报错,如果没有default,在使用时必须赋值。
使用自定义注解,如下:
@MyAnnotation()
public class AnnotationTest {
@MyAnnotation()
Private String name;
@MyAnnotation()
public void test() {
}
}
总结:注解在Java开发过程中越来越多,也越来越重要,尤其使用Spring相关框架,注解开发比重很大。首先我们要知晓注解,才知道Spring注解的含义,作用是什么,Spring也是根据Java注解要求自定义相关注解,让我们程序员使用;同时注解应与Java反射机制搭配使用,才能发挥注解作用,Spring框架是通过反射获取某个类、方法或属性上的注解,然后帮助我们开启了很多功能,同时Spring的Aop、Ioc等相关功能也是基于注解、反射和动态代理实现的。
我们需要先了解Java注解和反射,再使用Spring相关功能或研读Spring源码时才不会一脸懵逼,因为之前的我就是这样😂。后续我会写一篇反射文章,然后结合注解和反射,再聊一聊。
以上内容如有问题,请各位老师在评论区指定和讨论,本人虚心接受并认真学习。