JAVA中的注解:注解的作用+注解的类型(内置注解、元注解、自定义注解)+注解的实现
1.什么是注解
-
注解的作用
-
注解一般用于对程序的说明,就像注释一样,但是区别是注释是给人看的,注解是给程序看的
-
让编译器进行编译检查的作用,比如@Override修饰的方法,表示是重写父类的方法,如果改动了方法名,就编译报错
public class Parent { public void sleep(){ } }
这里如果修改sleep方法名就会报错,因为sleep是重写的父类中的方法
public class Child extends Parent{ @Override public void sleep(){ } }
-
-
注解的格式
注解是以“@注解名”在代码当中存在的,还可以添加一些参数值,例如@SupperssWarnings(value=“unchecked”)
-
注解在哪里使用
可以附加在pakage、class、method、field(字段)等上面,相当于给他们添加了额外的辅助信息,以后可以通过反射来获取这些注解信息
2.注解的类型
一般常用注解分为三类
内置注解
-
@Override:修饰方法的,表示这个方法重写了父类方法
-
@Deprecated:修饰方法、属性、类,表示不鼓励程序员使用这些元素,通常是因为它很危险或者存在更好的方法,通俗说就是遗弃
@Deprecated public static void run(){ }
-
@SuppressWarnings:用来抑制编译时的警告信息,其参数如下含义:
-
deprecation:使用了过时的类或方法的警告
-
unchecked:执行了未检查时的转换时的警告
-
path:在类路径、源文件路径等中有不存在的路径警告
-
all:以上所有情况的警告
一个@SuppressWarnings(value=“unchecked”)
多个@SuppressWarnings(value={“unchecked”,“deprecation”})
@SuppressWarnings(value = "all") public void sleep(){ List list = new ArrayList<>(); } //消除了所有警告
-
元注解
元注解是用于注解注解的(对注解的解释说明),java中提供了4个元注解
-
@Target注解(用来描述注解的使用范围)其参数值:TYPE(类,接口等)、FIELD(变量)、METHOD(方法)、PACKAGE(包)、PARAMETER(方法参数)等
-
@Retention注解(用来描述注解什么时候还有效,用来描述注解的生命周期)其参数值:SOURCE(源文件保留)、CLASS(编译期保留,默认值)、RUNTIME(运行期保留,可以通过反射获取注解信息,一般自定义注解都使用这个值)
@MyAnnotation public class AnnotationDemo { //如果用在变量上面@MyAnnotation,这里会报错,只能用在类和方法上 int a = 0; @MyAnnotation public void run(){ } } @Target(value = {ElementType.METHOD,ElementType.TYPE}) //传入的是枚举类型,注解只能用在类和方法上 @Retention(value = RetentionPolicy.RUNTIME) @interface MyAnnotation{} //这里是定义的注解
-
@Documented注解(用来标注生成javadoc的时候是否会被记录,了解)
-
@Inherited注解(使被它修饰的注解具有继承性)
自定义注解
-
@interface是用来声明一个注解,格式public @interface 注解名{}
-
注解其中的每一个方法实际上是声明了一个配置参数
@Target(value = {ElementType.METHOD,ElementType.TYPE}) //传入的是枚举类型,注解只能用在类和方法上 @Retention(value = RetentionPolicy.RUNTIME) //自定义注解 MyAnnotation public @interface MyAnnotation { String name(); }
//注解的使用 @MyAnnotation(name = "aaa") public class AnnotationDemo { //如果用在变量上面@MyAnnotation,这里会报错,只能用在类和方法上 int a = 0; @MyAnnotation(name = "bbb") public void run(){ } }
-
方法名称就是参数的名称
-
返回值的类型就是参数类型
-
可以通过default
@Target(value = {ElementType.METHOD,ElementType.TYPE}) //传入的是枚举类型,注解只能用在类和方法上 @Retention(value = RetentionPolicy.RUNTIME) public @interface MyAnnotation { String name() default "1234"; }
//此时可以不用给参数 @MyAnnotation public class AnnotationDemo { //如果用在变量上面@MyAnnotation,这里会报错,只能用在类和方法上 int a = 0; @MyAnnotation(name = "bbb") public void run(){ } }
-
如果只有一个方法,也就是只有一个参数时,一般参数名称建议使用value,因为value在使用参数名时可以省略
@Target(value = {ElementType.METHOD,ElementType.TYPE}) //传入的是枚举类型,注解只能用在类和方法上 @Retention(value = RetentionPolicy.RUNTIME) public @interface MyAnnotation { String value() default "1234"; }
@MyAnnotation public class AnnotationDemo { //如果用在变量上面@MyAnnotation,这里会报错,只能用在类和方法上 int a = 0; @MyAnnotation("bbb") public void run(){ } }
-
注解参数必须有值,如果没有设置默认值,必须要使用该参数并且赋值
3.注解实现
- 自定义注解
- 在一个类上使用注解
- 通过反射获取注解信息
package com.test01;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyWebServlet {
String url() default "";
}
package com.test01;
@MyWebServlet(url = "/MyServlet")
public class MyServlet {
}
package com.test01;
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
Class cl = Class.forName("com.test01.MyServlet");
//获取注解信息
MyWebServlet myWebServlet = (MyWebServlet) cl.getDeclaredAnnotation(MyWebServlet.class);
System.out.println(myWebServlet.url());
}
}
输出结果: