注解
注解的概念,作用
- 什么是“注解”:JDK1.5提出“注解”。在我们编写代码的时候,使用@Override,@FactionalInterface,@Test(JUnit),这些注解都是写在“源码”中。作为一个“标记”,告诉“注解解析器”怎样编译、运行下面的代码。
- 告诉编译期中的“注解解析器”下面的代码应该怎样编译
- 使用“注解解析器”来加载有“注解”的代码,根据注解的使用,来决定怎样执行下面的代码
- 实现注解的两个元素:
- 注解本身–我们可以自定义注解,注解本质上是一个“接口”。但定义时有自己的关键字@interface
- 注解解析器–一个类。如果“注解”时给编译器用的,就需要将“注解解析器”随着编译器一起启动。否则这个“注解”就应该有一个单独的“注解解析器”来单独启动,加载使用了注解的类,来决定怎样去执行。
自定义注解的基本格式:
- 我们可以自定义注解:
语法:public @interface 注解名{
}
- 示例代码:
public @interface MyTest {
}
//使用这个注解:
import org.junit.Test;
@MyTest
public class Student {
@MyTest
private String name;
@Test
@MyTest
public void show(){
System.out.println("show()...");
}
}
- 这个注解有两个问题:
- 我们的注解可以放在一个类的任意位置—而@Test注解只能用在“方法”上
- 我们的注解没有任何作用—因为没有注解解析器。
这两个问题全部由“元注解”解决!!!
元注解
-
元注解:它也是一个注解,是JDK中定义好的,元注解只用在“注解的定义上”,它可以约束新注解:
- 使用的位置
- 生命周期
-
使用位置:@Target元注解
ElementType.METHOD是@Target注解的“属性”,如果像约束新注解只能用在:成员方法上。@Target(ElementType.METHOD) public @interface MyTest{ }
它的可选有:- ElementType.TYPE:类,接口
- ElementType.FIELD:成员变量
- ElementType.METHOD:成员方法
- ElementType.PARAMETER:方法参数
- ElementType.CONSRUCTOR:构造方法
- ElementType.LOCAL_VARIABLE:局部变量
-
生命周期:@Retention元注释
例如:@Retention(RetentionPolicy,SOURCE),约束新注释只存在于“源码中”,不会被编译到class中
RetentionPolicy.SOURCE是@Rentention元注释的“属性”,它的可选值:- RetentionPolicy.SOURCE:注释只存在于“源码”中,例如:@Override
- RetentionPolicy.CLASS:注释可以存在于“源码”,“class”文件中
- RetentionPolicy.RUNTIME:注释可以存在于“源码”,“class文件”,运行时会被加载到内存。例如:@Test
代码演示:
自定义注解
@Target({
ElementType.METHOD})//1.约束新注解:使用的位置
@Retention(RetentionPolicy.RUNTIME)//2.约束新注解:生命周期
public @interface MyTest {
}
代码图解
解析注解
- 这里我们单独编写一个“类”,包含main()方法,作为我们自定义的注解@MyTest注解的“注解解析器”,来模拟JUnit的@Test的注解解析器。
- 在这个“注解解析器”中,需要使用“反射”技术
- 步骤:
- 编写一个注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)