java注解的概念及其使用方法详细介绍

news2024/11/15 22:26:12
1_注解:概述

路径

  1. 什么是注解
  2. 注解的作用

注解

什么是注解?

  • 注解(Annotation)也称为元数据,是一种代码级别的说明
  • 注解是JDK1.5版本引入的一个特性,和类、接口是在同一个层次
  • 注解可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明

注解:就是具有特殊含义的标记(注解是给机器阅读的)

注解的作用

注解就是在代码里添加一些特殊标志,这些标志可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行操作

注解的作用:

  1. 编译检查

    • @Override:用来修饰方法声明。
    • 用来告诉编译器该方法是重写父类中的方法,如果父类不存在该方法,则编译失败

    在这里插入图片描述

  2. 代码分析:

    • 通过代码里标识的注解对代码进行分析

    • 框架的配置( 框架 = 代码 + 配置 )

      • 具体使用请关注框架课程的内容的学习(注解去配置数据)
  3. 生成帮助文档

    • @author:用来标识作者姓名

    • @version:用于标识对象的版本号,适用范围:文件、类、方法

      • 使用@author和@version注解就是告诉Javadoc工具在生成帮助文档时把作者姓名和版本号也标记在文档中

        在这里插入图片描述

使用过的注解:

  • @Override
    • 用来修饰方法声明,告诉编译器该方法是重写父类中的方法,如果父类不存在该方法,则编译失败
  • @Test
    • Junit测试注解
  • @FunctionalInterface //函数式接口

小结

注解:在代码中添加的标记,JVM看到注解标记后会执行一些操作

注解的作用:

  • 编译检查
  • 运行时代码分析
  • 生成文档
2_注解:自定义注解

路径

  1. 注解的定义格式
  2. 定义带有属性的注解

注解的定义格式

定义注解使用关键字:@interface

public @interface 注解名{
   //内容
}

注解本质上就是一个接口。所有注解都会继承一个接口:Annotation

public interface 自定义注解名 extends java.lang.annotation.Annotation {}

带有属性的注解

  1. 属性的格式

    • 格式1:数据类型 属性名(); //无默认值的属性
    • 格式2:数据类型 属性名() default 默认值; //有默认值的属性
  2. 属性定义示例

    public @interface Student {
      String name();                // 姓名
      int age() default 18;         // 年龄
      String gender() default "男"; // 性别
    } 
    // 该注解就有了三个属性:name,age,gender
    
  3. 属性适用的数据类型【记住】

    1. 八种数据数据类型(intshortlongdoublebytecharbooleanfloat)
    2. StringClass,注解类型,枚举类
    3. 以上类型的一维数组形式
    

小结

注解的定义格式:

public @interface 注解名
{
    //属性格式 :  数据类型 属性名()
    String 属性名();
    int 属性名() default 默认值;
}
//注意:属性的类型只能是8种基本数据类型、String、Class、枚举、注解、(以及一维数组形式)
       
3_注解:注解的使用

路径

  1. 注解的使用格式
  2. 案例代码
  3. 特殊属性value

注解的使用格式

格式:

//无属性注解
@注解名                      例:@Test

//有属性注解
@注解名(属性=值,属性=值)

注解可以在类上,成员变量上,构造方法上,方法上,参数上…

有默认值的属性,可以不用进行赋值。

案例代码

将Book注解使用起来

public @interface Book {
    String name();

    double price() default 100.0;

    String[] author();
}

建立一个BookStore的类,在类中定义成员变量,构造方法,成员方法

@Book(name = "西游记", author = {"吴承恩", "张三"})
public class BookStore {
    @Book(name = "三国", price = 10, author = {"罗贯中"})
    private String book;

    @Book(name = "三国", price = 10, author = {"罗贯中"})
    public BookStore() {
    }


    @Book(name = "三国", price = 10, author = {"罗贯中"})
    public void test() {

    }
}

特殊属性value

如果注解中只有一个属性要赋值,而且名字是value,可以将value给省略,可以直接给值

@interface A{
    String value();
}

@interface B{
    String value();
    String name();
}

@interface C{
    String value();
    int price() default 100; //有默认值
}
//测试类
public class Demo {
    @A("值")  //当自定义注解中仅有一个value属性时,可以省略value属性名
    public void test1() {
    }

    @B(value = "值",name="aa") //当自定义注解中除了value属性外,还有其它属性,value不能省略
    public void test2() {

    }

    @C("值")//自定义注解中除了value属性外,还有其它带有默认值的属性,value可以省略
    public void test3() {

    }
}

小结

自定义注解:

public @interface Book{
    //属性
    String name();
    double price() default 100;
}

在程序代码中使用自定义注解:

//注解可以应用在:类、方法、变量、构造方法

@Book(name="属性值")  //price属性使用默认值
public class BookStore{
    
    @Book(name="属性值",price="新的值") //新的price值,会覆盖默认值
    public void method(){
        
    }
}
    1.如果自定义注解中的属性不给默认值,那么使用的时候必须赋值,如果有默认值,使用的时候可以不给值
    2.使用注解:@注解名(属性名=属性值,属性名=属性值,....)
    3.如果注解中没有属性,使用的时候@注解名
    4.如果属性是数组,那么赋值方式:
        @注解名(属性名=属性值,属性名=属性值,属性名={属性值,属性值,..}....)
    5.如果属性是数组类型,并且使用的时候只给一个值,那么可以省略大括号
    6.如果属性只有一个并且属性名是value,那么给value赋值的时候可以不写value
    7.如果含有多个属性,并且没有默认值,那么给value赋值的时候必须书写value
    8.如果含有多个属性,并且具有默认值,那么给value赋值的时候可以不写value
    9.同一个注解不能同时修饰同一个方法或者同一个类
    10.不同注解可以同时修饰同一个方法或者同一个类
4_注解:元注解

路径

  1. 元注解的作用
  2. 常用的元注解
  3. 元注解的使用

元注解的作用

默认情况下,注解可以用在任何地方,比如类,成员方法,构造方法,成员变量等地方

如果要限制自定义注解的使用位置怎么办?那就要学习一个新的知识点:元注解

结论:元注解是用来约束自定义注解的使用范围、生命周期

常用的元注解

常用元注解:@Target、@Retention

@Target

  • 作用:指明此注解用在哪个位置,如果不写默认是任何地方都可以使用
  • @Target可选的参数值在枚举类ElemenetType中包括:
    • TYPE: 用在类,接口上
    • FIELD:用在成员变量上
    • METHOD: 用在方法上
    • PARAMETER:用在参数上
    • CONSTRUCTOR:用在构造方法上
    • LOCAL_VARIABLE:用在局部变量上

@Retention

  • 作用:定义该注解的生命周期(有效范围)。
  • @Retention可选的参数值在枚举类型RetentionPolicy中包括:
    • SOURCE:注解只存在于Java源代码中,编译生成的字节码文件中就不存在了
      • 使用场景:针对一些检查性的操作,比如:@Override ,就使用SOURCE注解
    • CLASS:注解存在于Java源代码、编译以后的字节码文件中,运行的时候内存中没有,默认值
      • 使用场景:在编译时进行一些预处理操作,比如:生成一些辅助代码,就用CLASS注解
    • RUNTIME:注解存在于Java源代码中、编译以后的字节码文件中、运行时内存中,程序可以通过反射获取该注解
      • 使用场景:要在运行时去动态获取注解信息,那只能用 RUNTIME 注解

元注解的使用

@Target({ElementType.METHOD,ElementType.TYPE}) //元注解
@interface Stu{
    String name();
}

//类
@Stu(name="jack")  //成功
public class AnnotationDemo02 {
    // 成员变量
    @Stu(name = "lily")  // 编译失败
    private String gender;
    
    // 成员方法
    @Stu(name="rose")  //成功
    public void  test(){
    }
   
    // 构造方法
    @Stu(name="lucy") // 编译失败
    public AnnotationDemo02(){}
}

小结

元注解的作用:

  • 限定自定义注解的使用范围、生命周期
    • 限制使用范围:@Target
    • 限定生命周期:@Retention
5_注解:注解解析

路径

  1. 获取注解数据的原理
  2. 案例代码

获取注解数据的原理

想要对注解中的数据进行解析,需要借助:AnnotatedElement接口

  • Field,Method,Constructor,Class等类都是实现了AnnotatedElement接口

AnnotatedElement 是一个接口,定义了解析注解的方法:

1. boolean isAnnotationPresent(Class<Annotation> annotationClass)   
   判断当前对象是否使用了指定的注解,如果使用了则返回true,否则false
   
   public class BookStore{
       
       @Book(name="书名")
       public void buy() // Method对象 判断该对象上是否使用了@Book注解
       {                 // boolean flag = Method对象.isAnnotationPresent(Book.class)
       }
   } 
    
  
2. T getAnnotation(Class<T> annotationClass) 
   根据注解类型获得对应注解对象
   // 获取对象上的自定义注解
   // Book bookAnno = Method对象.getAnnotation(Book.class); 
   //      bookAnno.属性   //获取注解中属性的值
    

Class,Constructor,Method,Field都会实现AnnotatedElement 接口

  • 解析类型上的注解:借助字节码对象(Class对象)
  • 解析构造方法上的注解:借助构造器对象(Constructor对象)
  • 解析方法上的注解:借助方法对象(Method对象)
  • 解析字段上的注解:借助字段对象(Field对象)

注解解析的步骤:(注解是书写在:类、方法、变量上)

1、利用反射技术获取注解作用的对象:类、方法、变量、构造方法

2、判断对象上是否有自定义注解存在

3、有:获取对象上的自定义注解

4、使用获取到的自定义注解对象,拿到注解中的属性值

注意:注解解析必须保证自定义注解生命周期在RUNTIME(程序运行中)

案例代码

需求如下:

  1. 定义注解Book,要求如下:
    • 包含属性:String value() 书名
    • 包含属性:double price() 价格,默认值为 100
    • 包含属性:String[] authors() 多位作者
    • 限制注解使用的位置:类和成员方法上 【Target】
    • 指定注解的有效范围:RUNTIME 【Retention】
  2. 定义BookStore类,在类和成员方法上使用Book注解
  3. 定义TestAnnotation测试类获取Book注解上的数据
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD,ElementType.TYPE}) //使用范围:方法、类
@Retention(RetentionPolicy.RUNTIME) //保证注解在程序执行时有效(适用于注解解析)
public @interface Book {
    String value();
    double price() default 100;
    String[] authors();
}


//类
public class BookStore {
    @Book(value = "Java入门", authors = {"张老师", "毕老师"})
    public void buy() {
        System.out.println("购书.....");
    }
}

//对注解中的数据进行解析
public class TestBookStore {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //反射套路:1、Class  2、构造器   3、Method
        Class<BookStore> bookStoreClass = BookStore.class;

        //获取构造器
        Constructor<BookStore> con = bookStoreClass.getConstructor();
        BookStore bookStore = con.newInstance();//实例化对象

        //获取Method
        Method method = bookStoreClass.getMethod("buy");

        //解析注解的步骤
        if(method.isAnnotationPresent(Book.class)){
            //获取Method对象上的Book注解
            Book bookAnno = method.getAnnotation(Book.class);

            //获取注解上的数据
            String bookName = bookAnno.value();
            double bookPrice = bookAnno.price();
            String[] bookAuthors = bookAnno.authors();

            System.out.println("书名:"+bookName);
            System.out.println("价格:"+bookPrice);
            System.out.println("作者:"+ Arrays.toString(bookAuthors));
        }
    }
}

小结

注解解析的步骤:

  1. 利用反射技术获取相关的对象:类、构造器、方法、变量
  2. 使用方法getAnnotation,获取自定义注解对象
  3. 使用注解对象,分别获取注解中的属性值

注解扩展小示例:

public class Student{
    private String name;//姓名
    private int age;//年龄
    private String gender;//性别
    private double score;//成绩
    private String id;//学号
}
数据:
    张三,20,,90,it1001

利用注解+反射,给Student类中的成员变量赋值

//自定义注解
public @interface Entity{
    String value;
}
//Student类
public class Student{
    @Entity(value="张三")
    private String name;//姓名
    
    @Entiry(value="20")
    private int age;//年龄
    
    private String gender;//性别
    
    private double score;//成绩
    
    private String id;//学号
}
6_注解:综合案例

目标

路径

  1. 案例需求
  2. 案例分析
  3. 案例代码

需求

需求:模拟Junit测试的@Test

案例分析

  1. 模拟Junit测试的注释@Test,首先需要编写自定义注解@MyTest,并添加元注解,保证自定义注解只能修饰方法,且在运行时可以获得。
  2. 然后编写目标类(测试类),然后给目标方法(测试方法)使用 @MyTest注解,编写三个方法,其中两个加上@MyTest注解。
  3. 最后编写调用类,使用main方法调用目标类,模拟Junit的运行,只要有@MyTest注释的方法都会运行

案例代码

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//自定义注解
@Target(ElementType.METHOD)//仅能应用在方法上
@Retention(RetentionPolicy.RUNTIME)//生命周期 :运行时
public @interface MyTest {
    //无属性注解
}


public class TestAnnotationParse {

    //方法1
    @MyTest
    public void method1(){
        System.out.println("我是方法1");
    }

    @MyTest
    public void method3(){
        System.out.println("我是方法3");
    }


    public void method2(){
        System.out.println("我是方法2");
    }

}



public class Test {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException {
        //获取Class对象
        Class<TestAnnotationParse> testAnnotationParseClass = TestAnnotationParse.class;

        //获取Class对象中,所有的Method方法
        Method[] methods = testAnnotationParseClass.getMethods();
        
        //遍历数组
        for (int i = 0; i < methods.length; i++) {
            //获取每一个Method对象
            Method method = methods[i];

            //判断Method对象上,是否存在@MyTest
            if(method.isAnnotationPresent(MyTest.class)){
                method.invoke(testAnnotationParseClass.newInstance());
            }
        }
    }
}

小结

注解解析的步骤:

  1. 获取Class对象 //类名.class、对象名.class、Class.forName(“…”)
  2. 基于Class对象,来获取:构造器/成员方法/成员变量 //getConstructor() getMethod() getField()
  3. 基于构造器/成员方法/成员变量,判断是否存在自定义注解 // isAnnotationPresent(注解.class)
  4. 存在:获取自定义注解对象 // 注解 对象 = 构造器/方法/变量/类 .getAnnotation(注解.class)
  5. 基于自定注解对象,获取其属性值 // 注解对象.属性()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1869677.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WPF----进度条ProgressBar(渐变色)

ProgressBar 是一种用于指示进程或任务的进度的控件&#xff0c;通常在图形用户界面&#xff08;GUI&#xff09;中使用。它提供了一种视觉反馈&#xff0c;显示任务的完成程度&#xff0c;帮助用户了解任务的进展情况。 基本特性 Minimum 和 Maximum 属性&#xff1a; 这些属…

智能充电桩网关,构建高效充电网络

近年来我国新能源汽车的增长速度出现明显的上升趋势&#xff0c;但是其充电桩的发展还比较缓慢。目前在充电桩系统设计期间仍存在一些问题&#xff0c;主要表现在充电设施短缺、充电难等问题&#xff0c;这些问题的发生均会在一定程度上限制新能源汽车的发展&#xff0c;这就需…

华宽通中标长沙市政务共性能力建设项目,助力智慧政务建设新飞跃

在数字化浪潮的推动下&#xff0c;长沙市政府正积极拥抱智慧城市建设&#xff0c;以科技力量提升政务服务效能。华宽通凭借其卓越的技术实力与丰富的项目经验&#xff0c;成功中标长沙市政务共性能力建设项目&#xff0c;这无疑是对华宽通在智慧城市领域实力的高度认可。 华宽…

基于springboot、vue汽车租赁系统

设计技术&#xff1a; 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatisvue工具&#xff1a;IDEA、Maven、Navicat 主要功能&#xff1a; 用户进入系统可以查看首页、个人中心、车辆信息管理、租赁订单列表管理、还车记录管理等操作 管理…

亚马逊卖家的ERP代理贴牌与独立部署策略

贴牌&#xff0c;就是将亚马逊ERP进行个性化定制&#xff0c;包括更换成自己公司的logo、域名、收款账户&#xff0c;同时支持与自己的物流渠道进行对接&#xff0c;以满足自建仓库的需求。 对于独立部署&#xff0c;这需要有自己的服务器、数据库和存储空间等基础设施。在贴牌…

向量化算法 doc2vec

第1关&#xff1a;认识 Doc2vec Doc2vec 算法简介 Doc2vec 又叫做 Paragraph2vec&#xff0c; Sentence embeddings&#xff0c;是一种非监督式算法&#xff0c;可以获得句子、段落、文档的向量表达&#xff0c;是 Word2vec 的拓展。学出来的向量可以通过计算距离来找句子、段…

别人工作8小时,我只需1小时!这些宝藏网站我都替你收集好了!

关注公众号【程序员世杰】&#xff0c;回复【宝藏网站】即可获得跳转链接 软件 mac应用下载 很多破解版应该都可以找到 snipaste&#xff1a; 截图工具&#xff0c;快捷截图&#xff0c;贴图等功能。 幕布&#xff1a; 快速编辑思维导图。 sublime text: 文档编辑器&…

吴恩达2022机器学习专项课程C2W3:2.27 选修_数据倾斜

目录 处理不平衡数据集1.分类需求描述2.计算精确率和召回率 权衡精确率和召唤率1.手动调整阈值2.F1分数 总结 处理不平衡数据集 1.分类需求描述 如果你在处理一个机器学习应用&#xff0c;其中正例和负例的比例&#xff08;用于解决分类问题&#xff09;非常不平衡&#xff0…

【b站-湖科大教书匠】3 数据链路层-计算机网络微课堂

课程地址&#xff1a;【计算机网络微课堂&#xff08;有字幕无背景音乐版&#xff09;】 https://www.bilibili.com/video/BV1c4411d7jb/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 3 数据链路层 3.1 数据链路层概述 3.1.1 数据链路层在网络体系结…

深度学习 --- stanford cs231学习笔记五(训练神经网络之数据的预处理)

数据的预处理(Data Preprocessing) 2 Data Preprocessing数据的预处理 数据预处理的几种方法 2&#xff0c;1 数据的零点中心化 数据的零点中心化的目的就是为了把数据的整体分布拉回到原点附近&#xff0c;也就是让数据的整体均值变为0。 ​ 2&#xff0c;2 数据的标准化 数据…

介绍ES6中的class类:(一) 类的基本语法

一、类的由来与简介 1. 简介 很早很早之前&#xff0c;在JavaScript的世界里&#xff0c;生成实例对象的传统方法是通过构造函数。 嗯哼&#xff1f; function Point(x, y) {this.x x;this.y y; }Point.prototype.toString function () {return ( this.x , this.y )…

MATLAB2024a下的BP神经网络回归工具箱预测

1 打开BP神经网络回归工具箱GUI界面 图1-1 如图1-1所示&#xff0c;虽然叫神经网络拟合但确实是BP神经网络回归工具箱&#xff0c;如果想要使用其他神经网络模型&#xff0c;可以打开左边的深度网络网络设计器&#xff0c;如图1-2、图1-3所示&#xff1a; 图1-2 图1-3 2 导入训…

Java操作Word文档

文章目录 Java操作Word文档引言1、技术选型结论 2、基础文本填充2.1 引入依赖2.1.1. poi2.1.2. poi-ooxml2.1.3. poi-ooxml-schemas 总结2.2 业务思路2.3 业务层 OfficeService2.4 通用工具类 OfficeUtils2.5 控制层 OfficeController 3、表格3.1 准备模板3.2 业务层 OfficeSer…

NVIDIA控制面板3D设置一栏中不能通过预览更改图形设置的解决办法

今天因为GeForce Experience弹窗让我更新之后&#xff0c;手欠直接删掉了 然后图中标出的两个选项就没了 解决方法很简单&#xff0c;就是下回来&#xff0c;hhh https://www.nvidia.cn/geforce/drivers/ 直接下载就行&#xff0c;不用管版本&#xff0c;但是这种驱动千万不要…

本地项目上传到GitHub上(李豆)

本地项目上传到GitHub上(李豆) 准备工作&#xff1a; 本地需要有 git 也需要有一个 GitHub 账号 首先需要在 GitHub 新建一个空仓库 在想要上传项目的文件夹中使用 Git 命令操作 初始化&#xff1a; git init与 github 仓库进行链接 &#xff1a;git remote add origin …

妙手ERP正式接入Lazada 3PF,支持批量设置产品库存,管理多仓发货

Lazada平台近期又有大动作&#xff0c;上线了3PF一店多运模式&#xff01; 一、Lazada 3PF一店多运模式 在介绍3PF一店多运模式前&#xff0c;要先说明一下原有的Lazada履约模式&#xff0c;此前&#xff0c;Lazada为跨境商家提供两大类物流履约方案&#xff1a; 一类&#x…

谷歌网络营销中SEO的策略有哪些?

在网络营销中&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;是一种关键策略&#xff0c;旨在提高网站在搜索引擎结果中的排名。首先&#xff0c;要进行关键词研究&#xff0c;找出潜在客户使用的搜索词。接下来&#xff0c;优化网站内容&#xff0c;使其包含这些关键词&…

Android高级面试_8_热修补插件化等

Android 高级面试&#xff1a;插件化和热修复相关 1、dex 和 class 文件结构 class 是 JVM 可以执行的文件类型&#xff0c;由 javac 编译生成&#xff1b;dex 是 DVM 执行的文件类型&#xff0c;由 dx 编译生成。 class 文件结构的特点&#xff1a; 是一种 8 位二进制字节…

“必答题”-中小制造企业如何做好数字化转型

实现数字化转型是当前中小制造企业生存下去的重要保障。通过数字化转型&#xff0c;中小企业可以充分利用数字技术对其生产、运营、管理等环节进行全链路的改造和应用&#xff0c;提升企业的竞争力。 那么&#xff0c;中小制造企业的数字化要如何做&#xff1f; 中小制造企业数…

LLM在软件测试中的革新应用

一、引言 随着人工智能技术的蓬勃发展&#xff0c;大语言模型&#xff08;Large Language Model&#xff0c;简称LLM&#xff09;如GPT系列&#xff0c;在自然语言处理领域取得了显著进展。LLM不仅能够处理复杂的自然语言任务&#xff0c;还在多个领域展现出广泛的应用潜力。在…