Java-注解的介绍,定义,使用,解析和实现

1.注解的介绍

注解(Annotation)是一种标记,注解可以使用在源码中

注解可以使用在以下的位置

  • 类上
  • 方法上
  • 成员变量上
  • 构造方法上
  • 局部变量上

当你在程序中使用了注解,编译器、DE或者程序可以通过反射来获取注解相关的信息,然后根据业务逻辑或者相关需求实现一些功能。

之前使用过的注解:

  • @Override方法重写在编译期起作用
  • @Functionallnterface标记接口是函数式接口在编译期起作用
  • @TestTestNG框架的注解,在运行期起作用

注解的作用

  • 1.生成帮助文档 @author @version @since
  • 2.执行编译期的检查
  • 3.框架的配置

后期学习框架时会使用到框架提供的很多注解。

2.自定义注解的定义和使用

自定义注解

注解可以包含属性,定义属性的格式:属性类型 属性名{}

为了让大家理解注解的属性,理解成接口的抽象方法,它有返回值,没有参数。

package com.itheima.demo;

/**
 * 我的注解测试
 *
 * @author YZH
 * @date 2023/12/20
 */
public @interface MyTest {
}

注解的属性类型有限制的,只能使用如下的数据类型

  • 1.8种基本数据类型
  • 2. String
  • 3.Class
  • 4.枚举
  • 5.注解
  • 6.以上数据类型的一维数组类型 

自定义注解-带有属性

package com.itheima.demo;

/**
 * 表
 *自定义注解,带有属性
 * @author YZH
 * @date 2023/12/20
 */
public @interface Table {
    /**
     * 表的编号
     *
     * @return long
     */
    long id();

    /**
     * 表名
     *
     * @return {@link String}
     */
    String name();

    /**
     * 表名的前缀
     *
     * @return {@link String}
     */
    String prefix();

}

注解的使用 

1.不带属性的

package com.itheima.maven.annotation;

import javax.xml.crypto.Data;
import java.sql.Date;

/**
 * 测试注解
 *
 * @author YZH
 * @date 2023/12/20
 */
// 在类上使用
@MyTest
public class MyTestAnnotation {
    // 在构造方法上使用
    @MyTest
    MyTestAnnotation(){}
    // 在方法上使用
    @MyTest
    public void showTime(@MyTest String string){
        // 在局部变量上使用
        @MyTest
        String str = "111";
        System.out.println(str);
    }
}

2.带属性的注解

注意:如果注解带有属性,所有属性都要赋值

package com.itheima.maven.annotation;

/**
 * 表注释使用测试
 *自定义注解的使用-带属性
 * @author YZH
 * @date 2023/12/20
 */
public class TableAnnotationUsageTest {
}
@Table(id=1,name = "employee",prefix = "tbl_")
class Employee{

}

 4.注解的属性可以有默认值,默认值的格式属性类型属性名(default默认值;String prefix()  default "tbl_";

3.元注解

之前自定义的注解在任何地方都可以使用,通过元注解显示注解使用的位置

元注解就是在注解之上使用的注解,其作用就是为了标记自定义注解。

元注解有两个

Target 表示注解可以作用在什么位置上,默认就是任何位置

  • ElementType.TYPE注解可以使用在类上
  • ElementType.FIELD注解可以使用在成员变量
  • ElementType.METHOD注解可以使用在方法上
  • ElementType.PARAMETER注解可以使用在方法的参数上
  • ElementType.CONSTRUCTOR注解可以用在构造方法上
package com.itheima.maven.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

/**
 * 自定义注解
 *注解只能用在方法上
 * @author YZH
 * @date 2023/12/20
 */
@Target(ElementType.METHOD)
public @interface Test {
}

etention :定义注解保留到什么阶段,默认是源码阶段

什么阶段指的是Java程序的运行过程的三个阶段:源码阶段、编译阶段、运行阶段

  • RetentionPolicy.SOURCE源码阶段
  • RetentionPolicy.CLASS编译阶段·
  • RetentionPolicy.RUNTIME运行阶段

运行阶段包含编译阶段和源码阶段

编译阶段包含源码阶段

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}

4.注解的解析

JDK自带的注解由JDK提供对应的功能。

目前为止自定义的注解没啥功能。因此想要自定义的注解有些功能,得自己通过反射的API去实现。

Class,Method,Filed,Construtor反射的APl都实现了一个接口java.lang.reflect.AnnotatedElement。

AnnotatedElement接口的重要方法

  • T getAnnotation(class annotationclass);获取指定class的注解,如果没有返回nullI
  • default boolean isAnnotationPresent(class annotationclass)是否存在指定class的注解

1.获取类上的注解以及注解的属性信息

 

package com.itheima.maven.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * 表
 *自定义注解,带有属性
 * @author YZH
 * @date 2023/12/20
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    /**
     * 表的编号
     *
     * @return long
     */
    long id();

    /**
     * 表名
     *
     * @return {@link String}
     */
    String name();

    /**
     * 表名的前缀
     *
     * @return {@link String}
     */
    String prefix() default "tb_";

}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}

 

package com.itheima.maven.annotation;

import org.junit.jupiter.api.Test;

/**
 * 解析注解
 *
 * @author YZH
 * @date 2023/12/20
 */
public class AnnotationProcessTest {
    @Test
    public void processTableAnnotation(){
        Class employeeClass = Employee.class;
        // 获取Employee的注解
        Table tableAnnotation = employeeClass.getAnnotation(Table.class);
        // 注解的类型信息
        System.out.println("注解的类型信息:"+tableAnnotation);
        // 获取注解的属性值
        System.out.println(tableAnnotation.id());
        System.out.println(tableAnnotation.name());
        System.out.println(tableAnnotation.prefix());

    }
}

2.获取类中成员变量的注解

package com.itheima.maven.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 *
 *
 * @author YZH
 * @date 2023/12/20
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String name();
}

 

 @Test
    public void processColumnAnnotation(){
        Class employeeClass = Employee.class;
        try {
            Field nameFiled = employeeClass.getDeclaredField("name");
            Column columnAnnotation = nameFiled.getAnnotation(Column.class);
            // 注解的类型信息
            System.out.println("注解的类型信息:"+columnAnnotation);
            // 获取注解的属性值
            System.out.println(columnAnnotation.name());
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

5.实现@Test注解

你可能感兴趣的:(java,开发语言)