1.注解介绍
1.注解是一种元数据(任何文件系统中的数据分为数据和元数据。数据是指普通文件中实际数据,而元数据只用来描述一个文件特征的系统数据,例如访问权限等)形式,即注解是属于java的一种数据类型,和类,接口,数组,枚举类似
2.怎样自定义注解
- 定义注解
- 使用注解(将注解打在需要的代码上)
- 解析注解(标记注解并进行特殊操作)
2.1注解基本语法
注解类声明
本质:注解本身就是一个接口,该接口默认继承java.lang.annotation.Annotation
public interface MyLog extends java.lang.annotation.Annotation {
注解在java中,与类,接口,枚举类似,因此其声明语法基本一致,只是所使用关键有所不同@interface在底层实现上,所有定义注解都会自动继承java.lang.annotation.Annotation接口,
package day01.Demo01_Day017.JiaoXiao; public @interface MyLog { String value() default ""; }
注解元素声明
-
-
-
- 访问修饰符必须是publi,不写默认为public
- 该元素的类型只能是基本数据类型、String Class、枚举类型;
- 该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(后面使用会带来便利操作)
- ()不是定义方法参数的地方,也不能在括号定义任何参数,仅仅只是一个特殊的语法;
- default代表默认值,值必须和第二点定义的类型一致;
- 如果没有默认值,代表后续使用注解时必须给该类型元素赋值
-
-
2.2常用元注解
一个最基本的注解定义就只包括了上面的两部分内容:1,注解的名字;2,注解包含的类型元素。但是我们在使用注解的时候发现,有些注解只能写在方法上面;有些却可以写在类的上面
package day01.Demo01_Day017.JiaoXiao; import java.lang.annotation.*; @Inherited //当前注解只能放在方法以及类上 @Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyLog { String value() default ""; }
2.2.1@Target
@Target注解,是专门用来限定某个自定义注解能够被应用在哪些Java元素上面的。
枚举常量的含义:
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */
//接口、类、枚举
TYPE, /** Field declaration (includes enum constants) */
//字段、枚举的常量 FIELD, /** Method declaration */
//方法
METHOD, /** Formal parameter declaration */
//方法参数
PARAMETER, /** Constructor declaration */
构造函数
CONSTRUCTOR, /** Local variable declaration */
局部变量
LOCAL_VARIABLE, /** Annotation type declaration */
注解
ANNOTATION_TYPE, /** Package declaration */
包
PACKAGE, /** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * * @since 1.8 */ TYPE_USE, /** * Module declaration. * * @since 9 */ MODULE }
2.2.2 @Retention
@Retention注解,定义注解的保留策略
public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */
当注解被定义为RetentionPolicy.SOURCE,那么此注解只会出现Java源文件中,这个注解即不会参与编译也不会在运行时起任何作用。
SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */
当注解被定义为RetentionPolicy.CLASS,那么此注解将会被编译到class文件中,在运行期间同样不起任何作用。
CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */
当注解被定义为RetentionPolicy.RUNTIME,那么此注解可以在运行期间被加载到Class对象中。那么在程序运行阶段,我们可以通过反射得到这个注解及注解中的属性。
RUNTIME }
2.2.3 @Documented
@Documented注解,指定被修饰的该Annotation可以被javadoc工具提取成文档。
2.2.4 @Inherited
@Inherited注解,指定被修饰的Annotation将具有继承性
3.自定义注解的使用
3.1定义注解
package day01.Demo01_Day017.JiaoXiao; import java.lang.annotation.*; @Inherited //当前注解只能放在方法以及类上 @Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyLog { String value() default ""; }
3.2 使用注解
import org.junit.Test; public class CalculatorTest { /** * 初始化方法 * 用于资源 申请,所有测试方法在执行之前都会先执行该方法 */ @MyLog @Before @Test public void inti(){ System.out.println("我先执行了"); } /** * 释放资源方法 * 在所有测试方法执行完后,都会自动执行该方法 */ @After public void colose(){ System.out.println("俺被消灭了"); }
4.反射操作获取注解
package day01.Demo01_Day017.JiaoXiao; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Arrays; public class HelloController { public static void main(String[] args) throws Exception { Annotation[] annotation = HelloController.class.getAnnotations(); Arrays.asList(annotation).stream().forEach(System.out::println); Method hello = HelloController.class.getMethod("hello"); if (hello.isAnnotationPresent(MyLog.class)){ System.out.println("hello方法上配置MyLog注解"); MyLog annotation1 = hello.getAnnotation(MyLog.class); String value = annotation1.value(); System.out.println("MyLog注解value参数的值:"+value); }else { System.out.println("hello方法上没有配置MyLog注解"); } } }
MyLog 标签:java,MyLog,自定义,class,declaration,注解,public From: https://www.cnblogs.com/x3449/p/16789647.html