Java中的注解详讲

news/2024/9/25 3:39:16/

1 什么是注解

  • jdk5提供了一个新的应用 Annotation, 注解, 注释

  • 与之前所学的注释的区别

    • 之前的注释:是给程序员看 ,让程序员知道程序(代码)有什么用,实现了什么功能

    • 今天的注解:是给编辑器或jvm看的。在编译和运行时提供一些信息,按照信息完成后续的工作

      我们在开发中经常使用注解作为配置信息的载体。类似于xml配置文件的作用。

2 注解的分类

  1. 普通注解,在编程中经常用来作为配置的注解,包括jdk自带的注解和自定义注解

    • @Override 告诉编译,当前方法按照重写的规则检查。

    • @Deprecated 告诉编译器,当前说明的内容是过时的,不建议使用的。但可以继续使用

    • @SuppressWarnings 告诉编译,当前说明的内容相关的警告可以忽略

  2. 元注解,用来说明注解的注解 。 未来还有一个概念:元数据

    用户信息:dmy , 18 , 男, 30000

    元数据:姓名,字符串类型,最长10个字符 , 性别,年龄,工资

    元注解有4个

    • @Target 用来说明当前注解都可以作用在哪些内容上

java">@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
public @interface SuppressWarnings {}

   2.@Retention 用来说明当前注解存活范围,有3个范围, 只能3选1

java">RetentionPolicy.SOURCE;  //表示在原码到字节码编译过程中有效。编译后消失
RetentionPolicy.CLASS;	//表示在类加载过程中有效,加载完消失。
RetentionPolicy.RUNTIME;//表示在jvm运行时都有效。
  • 3.@Documented 用来说明当前注解在生成api文档时,会一同出现在文档中。

  • 4.@Inherited 用来说明当前注解在类继承的过程中,可以一同被继承。

3 注解语法结构

  • 注解是一个特殊的类,使用@interface 定义注解

java">public @interface A{}

 使用元注解,在普通注解头上来说明注解特性。至少要使用@Retention 和 @Target

java">@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface A {}

 注解里只能写一种内容 (可以称为属性 也 可以称为方法)

java">public @interface A{String i();
}
  • 该内容类型只能是以下几种

    • String

    • 8种基本类型

    • Class

    • 其他注解类型 , 当注解作为类型时,不需要加前面的@

    • 枚举类型

    • 上述所有类型的数组类型

  • 可以使用default关键字,为注解中的属性设置默认值

 

java">public @interface A{String name() default "dmy"  ;String[] names() default {"dmy","zs","ls"};
}

4 注解的使用

  • 使用注解,提供配置信息

    • 根据Target元注解的指定,可以在对应的类的内容上使用注解

    • 如果注解中有属性,可以在使用注解时,类似于传参的方式为属性赋值

    • 属性赋值时,需要指定属性名和其对应的属性值

    • 如果属性是数组类型,多个属性值要使用{}包含

java">@A(name="zhangsan",names={"zs","ls","ww"})
class B{}

 

特殊情况说明

  • 如果注解不需要传递属性值 (没有属性,都有默认值),后面的括号可有可无

java">@A()
@A
class B{}

 如果注解中只有一个属性需要赋值,且这个属性名叫value。赋值时可以只写值,不写名

java">@interface A{String value();
}

 如果注解属性是数组类型,且传参赋值时只赋予一个值,可以省略{}

java">@A(name="zs",names={"dmy"})
@A(name="zs",names="dmy")
class B{}

 

使用注解,获得配置信息

  • 注解在使用时,也是类的一部分

  • 可以通过反射获得注解,进而获得注解中配置的信息

  • 反射中常用的对象(Class,Field , Method , Constructor)都提供了获得注解对象的方法

java">@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface A {String value() ;
}

 

java">public class Test3 {public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {Class<B> c = B.class;A a = c.getAnnotation(A.class);System.out.println(a.value());Field i = c.getDeclaredField("i");Annotation[] annotations = i.getAnnotations();for(Annotation annotation : annotations){Method value = annotation.getClass().getMethod("value");Object v = value.invoke(annotation);System.out.println(v);}}
}@A("dmy")
class B{@A(value="dongmingyu",i="zs")@SuppressWarnings("all")int i ;
}

补充:所有的注解,都默认继承Annotation父注解类型

5 特殊情况的注解使用

  • 注解的重复使用

    • 默认情况下,无法使用两个相同的注解,修饰同一个类信息

    • 以前解决方案是定义一个新注解,新注解中有一个数组属性,可以包含多个所需要注解

java">@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AS {A[] value();
}
java">@AS({@A("zs") ,@A("ls") , @A("ww")
})
class B{}

 

  • 现在可以在注解上使用另一个注解@Repeatable(AS.class) 指定当前注解重复出现的时候,会自动的将重复的注解组成指定的那个@AS注解

    @AS还需要正常定义

java">@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(AS.class)
public @interface A {}@Target({ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AS {A[] value();
}

 

java">@A("zs")
@A("ls")
@A("ww")
class C{}

函数式接口

  • 这是lambda表达式相关的一个概念

  • lambda表达式针对的必须是接口,而且只能有一个抽象方法。这样的接口就称为函数式接口

  • 函数式接口,可以使用@FunctionalInterface声明。 在编译就会按照函数式接口的特点进行检测

 

java">@FunctionalInterface
interface A{void t1();
}
  • 使用注解声明,必须是函数式接口

  • 函数式接口,不一定使用注解声明

 


http://www.ppmy.cn/news/1519705.html

相关文章

arm64的windows可以玩英雄联盟

ARM64 架构的 Windows 设备&#xff08;如搭载 ARM 处理器的 Windows 笔记本&#xff09;能够运行像《英雄联盟》和 Photoshop 这样的应用&#xff0c;主要归功于微软在 Windows 操作系统中实现的兼容性技术&#xff0c;尤其是针对 x86 应用程序的仿真&#xff08;emulation&am…

NoSQL数据库-Redis集群详解及案例实现

一、 关系型数据库和 NoSQL 数据库 1.1 数据库主要分为两大类&#xff1a;关系型数据库与 NoSQL 数据库 关系型数据库&#xff0c;是建立在关系模型基础上的数据库&#xff0c;其借助于集合代数等数学概念和方法来处理数据库中的数据主流的 MySQL、Oracle、MS SQL Server 和 D…

数据仓库系列13:增量更新和全量更新有什么区别,如何选择?

你是否曾经在深夜加班时&#xff0c;面对着庞大的数据仓库&#xff0c;思考过这样一个问题&#xff1a;“我应该选择增量更新还是全量更新&#xff1f;” 这个看似简单的选择&#xff0c;却可能影响整个数据处理的效率和准确性。今天&#xff0c;让我们深入探讨这个数据仓库领域…

数据结构(邓俊辉)学习笔记】串 08——KMP算法:再改进

文章目录 1. 美中不足2. 以卵击石3. 前车之覆4. 后车之鉴5. 可视对比 1. 美中不足 以上&#xff0c;我们不仅给出了 KMP 算法&#xff0c;同时也证明它的时间复杂度已经达到了渐进意义上的最优&#xff0c;也就是最坏情况也不超过 O(n)。而该算法目前这个版本也绝非完美无缺&am…

黑马点评5——优惠券秒杀—优化秒杀

文章目录 Redis优化秒杀基于Redis完成秒杀资格判断 基于我们前面实现的优惠券的秒杀业务&#xff0c;我们接下来进行优化。 Redis优化秒杀 先回顾我们的业务流程 我们的秒杀过程中有很多个步骤都是去查询数据库&#xff0c;而我们知道&#xff0c;数据库的并发能力是比较弱的…

Python精选200+Tips:1-5

Pick a flower, You will have a world 001 list002 set003 dict004 tuple005 str运行系统:macOS Sonoma 14.6.1 Python编译器:PyCharm 2024.1.4 (Community Edition) Python版本:3.12 001 list 列表(list)是 Python 中一种用于存储有序元素的数据结构。以下是列表的基本…

前端框架大比拼:谁才是未来的主流选择?

前端框架包括Bootstrap、React、Vue.js等。在现代 Web 开发中&#xff0c;使用前端框架可以显著提升开发效率和页面性能&#xff0c;并简化响应式设计的实现过程。不同的框架提供了不同的功能和优势&#xff0c;因此选择适合项目需求的框架至关重要。下面将详细探讨这些主流前端…

Javascript实现笛卡儿积算法

在根据商品属性计算SKU时&#xff0c;通常会对商品不同选项的不同属性进行笛卡儿积运算。 function cartesian(elements) {if (!Array.isArray(elements))throw new TypeError();var end elements.length - 1,result [];function addTo(curr, start) {var first elements[s…