Java中的注解使用:全面性的总结一下
sinye56 2024-10-16 15:13 5 浏览 0 评论
前话:
今天,我们又来聊一下注解的使用,做一下详细的解析,也介绍了自定义注解,请耐心往下看哟!
注解的介绍:
在2005年,sun公司推出了jdk1.5,同时推出的注解功能吸引了很多人的目光,使用注解编写代码,能够减轻java程序员繁琐配置的痛苦。
使用注解可以编写出更加易于维护,bug更少的代码。
注解是什么呢?按照官方的说法,注解就是元标签,可以添加到你的代码,并应用于包声明、类型声明、构造函数、方法、字段、参数和变量。
注解提供了一种非常有用的方法来显示你编写的方法是否依赖于其他方法,它们是否完整,编写出的类是否引用了其他类,等等。
按照 Oracle官方 的说法,基于注解编写出的java代码会根据源代码中的注解生成模板代码,从而避免我们在大多数情况下编写模板代码。这导致了一种声明式编程风格,在这种风格中,程序员说要做什么功能,工具就写出相应的代码来实现它。
简而言之,注解是一种机制,用于将元标签与程序元素相关联,并允许编译器或虚拟机从这些注解元素中提取程序行为,并在必要时生成相互依赖的代码。
那么,现在就开始我们的java注解学习之旅。
内置注解
ava会内置一些已经实现好的注解,可以直接使用,内置的注解主要用于给java编译器提供指令。
Java内置的注解有五个:
- @Deprecated
- @Override
- @SuppressWarnings
- @SafeVarargs
- @FunctionalInterface
1. @Deprecated 注解主要用于给类、方法、变量打上不建议使用的标签,如果你的代码使用了不建议使用的类、方法、变量,编译器就会给你一个警告。
下面是使用@Deprecated的示例:
public class AnnotationTest { public static void main(String args[]){ MyAnnotation myAnnotation = new MyAnnotation(); int age = myAnnotation.age; myAnnotation.eat(); } } @Deprecated class MyAnnotation { @Deprecated int age; @Deprecated void eat(){ } }
定义了一个MyAnnotation,在类名,变量名和方法名上都使用的@Deprecated注解。
使用了@Deprecated标识的类、方法或变量时,
@Deprecated还有另外一个用处,就是在javadoc文档中写明类、方法或变量为什么不建议使用,并且给出替代方法:
@Deprecated /** @deprecated 已废弃,请使用MyNewComponent. */ class MyComponent { }
2.@Override注解在方法上使用,标识这个方法重写父类的方法。如果这个方法和父类方法不一致,编译器就会显示错误。
强烈建议在重写父类的方法上使用@Override注解,不用也不会有什么影响,但是如果不使用@Override注解,当有人修改父类的方法时,你就无法识别出子类的方法是否重写了父类的方法。而使用了@Override注解,只要父类没有这个方法,编译器就会提示父类没有对应方法的错误。
下面是使用@Override注解的示例:
class Anaimal{ public void run(){ } } class Cat extends Anaimal{ @Override public void run(){ } }
Cat类的run()方法使用了@Override注解,如果将Cat类中的方法改为run1(),编译器就会显示The method run1() of type Cat must override or implement a supertype 的错误。
如果不使用@Override注解,将Cat类中的方法改为run1(),系统则不会报错。
3.@SuppressWarnings注解也是在方法上使用,用于抑制警告,在调用deprecated的方法或者进行不安全的类型转化时,编译器会发出一些警告,使用@SuppressWarnings就可以忽略那些警告。
使用示例:
@SuppressWarnings public void methodWithWarning() { }
4.@SafeVarargs注解主要用于抑制参数类型安全检查警告,这个是jdk1.7新增的功能。
使用示例:
@SafeVarargs static void testSafeVarargs(List<String> ... stringLists) { Object[] array = stringLists; List<Integer> tmpList = Arrays.asList(42); array[0] = tmpList; String s = stringLists[0].get(0); }
如果不使用@SafeVarargs注解,编译器会给出警告信息:Type safety: Potential heap pollution via varargs parameter stringLists 。
使用@SafeVarargs有个前提,你必须保证某个使用了可变长度参数的方法,在与泛型类一起使用时不会出现类型安全问题。否则在运行行时会抛出 ClassCastException异常。
@SafeVarargs注解只能在满足如下条件的方法上使用:
- 参数长度可变的方法或构造方法。
- 方法必须声明为static或final。
5.@FunctionalInterface注解主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。
使用示例:
@FunctionalInterface interface GreetingService { void readMessage(String message); }
创建注解
注解的创建和接口有点类似,都是使用interface关检字,区别是创建注解时,需要在interface前面加上一个@字符。
下面是创建一个注解的例子:
public @interface MyAnnotation { }
上面创建注解没有任何成员变量。
创建带成员变量的注解:
@interface TestAnnotation{ int age(); String name(); }
TestAnnotation注解有两个成员变量,age和name。
注解的成员变量以无参数无方法体的方法形式声明。
使用default关键字指定注解成员变量的默认值:
@interface TestAnnotation{ int age() default 2; String name() default “小明”; }
使用自定义注解时,如果该注解的变量有默认值,可以不为成员变量指定值,直接使用默认值。
使用示例:
@interface TestAnnotation{ int age() default 2; String name() default "小明"; } class MyAnnotation { @TestAnnotation public void getInfo(){ } }
如果注解的变量没有默认值,在使用时必须为每个变量都指定值,代码如下:
@interface TestAnnotation{ int age(); String name(); } class MyAnnotation { @TestAnnotation(age=2,name="小明") public void getInfo(){ } }
元注解
什么是元注解呢?元注解就是注解的注解,也就是用于定义注解的注解,可以理解为注解的基础数据类型。这玩意真的很拗口,还是看代码比较舒服。
@Target(ElementType.METHOD) @interface Test_Target { public String doTestTarget(); }
@Target就是元注解,用于定义Test_Target注解。
java提供五种元注解,分别是:
- @Retention 指定注解的生命周期,即存活时间。
- @Documented javadoc命令生成的文档中体现注解的内容
- @Target 指定注解可用于哪些元素,例如类、方法、变量等
- @Inherited 注解的继承性,
- @Repeatable 可重复使用的注解
@Retention用于指定注解的生命周期,即存活时间。@Retention提供了如下的三个值,在使用@Retention时,必须使用其中的一个值。
- RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译生成class文件时丢弃,无法通过反射获取注解信息。
- RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到JVM中,无法通过反射获取注解信息,这是默认值。
- RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,程序运行时可以通过反射获取到它们。
下面是使用@Retention定义一个自定义注解的示例:
@Retention(RetentionPolicy.RUNTIME) @interface Test_Retention{ } @Test_Retention class MyAnnotation { public void getInfo(){ } }
上面的代码创建了一个Test_Retention的注解,并且使用@Retention指定Test_Retention注解可以保留到程序运行的时候(RetentionPolicy.RUNTIME),MyAnnotation使用@Test_Retention修饰,因此在运行时可以通过反射获取到MyAnnotation的注解信息。
@Documented如果类A使用了@Documented元注解注解的注解,那么在使用javadoc生成的类A的文档会包含有相应的注解信息。
使用示例:
@Documented @interface TestDocument{ String doTestDocument(); } @TestDocument (doTestDocument="保留注解信息测试") class MyAnnotation { public void getInfo(){ } }
@Target指定了注解所修饰对象的范围,可用于变量、参数、方法、包信息等。
@Target元注解提供如下的八个值:
- ElementType.ANNOTATION_TYPE 用于描述注解类型
- ElementType.CONSTRUCTOR 用于注解构造方法
- ElementType.FIELD 用于变量注解
- ElementType.LOCAL_VARIABLE 用于局部变量注解
- ElementType.METHOD 用于方法注解
- ElementType.PACKAGE 用于包注解
- ElementType.PARAMETER 用于方法内的参数注解
- ElementType.TYPE 用于类、接口、枚举注解
代码示例:
@Target(ElementType.METHOD) @interface TestMethodTarget{ } @Target(ElementType.FIELD) @interface TestFieldTarget{ } @Target(ElementType.TYPE) @interface TestTypeTarget{ }
TestMethodTarget注解只能用于注解类的方法,TestFieldTarget只能用于注解类的成员变量,TestTypeTarget可用于注解类、接口(包括注解类型) 或enum声明
@Inherited指定了注解可被继承。某个类使用了被@Inherited修饰的注解,那么那个注解也会用到该类的子类。
代码示例:
@Inherited @interface TestInherited{ }
@Repeatable同一个注解可多次使用。例如一个人有多种爱好,跑步、画画、看电影等。
示例代码:
@interface Persons { Person[] value(); } @Repeatable(Persons.class) @interface Person{ String hobby default ""; } @Person(hobby="runing") @Person(hobby="drawing") @Person(hobby="watching movies") public class Tom{ }
上面的代码,@Repeatable 注解了 Person。而 @Repeatable后面括号中的类相当于一个容器注解。
什么是容器注解呢?就是用来存放其它注解的地方。它本身也是一个注解。
上面详细介绍了注解的知识以及自定义注解的语法。现在我们来看下如何使用注解进行单元测试。
使用注解这要到反射的知识,关于反射的知识请看我的另外一篇文章“Java反射使用总结”。在得到反射对象后,要调用isAnnotationPresent方法这个对象是否包含指定类型的注解。 Annotation
示例代码:
public class Marathonrunner { @RuningTest public void test5km(){ System.out.println("进行5公里跑步测试"); } public void test10km(){ System.out.println("进行10公里跑步测试"); } @RuningTest public void test21km(){ System.out.println("进行21公里跑步测试"); } public void test42km(){ System.out.println("进行42公里跑步测试"); } } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @interface RuningTest{ } public class RuntestTool { public static void main(String args[]){ Marathonrunner xiaoming = new Marathonrunner(); Class clazz = xiaoming.getClass(); Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { if(method.isAnnotationPresent(RuningTest.class)){ try { method.setAccessible(true); method.invoke(xiaoming, null); } catch (Exception e) { } } } } }
运行结果:
进行21公里跑步测试 进行5公里跑步测试
上面的代码,我们定义了一个RuningTest注解,里面没有任何变量。这个注解使用@Retention和@Target元注解修饰,其中@Target元注解的值规定了这个RuningTest注解只能在方法上使用,而@Retention元注解值指定了在运行时可以获取到注解的信息。
定义了一个Marathonrunner马拉松远动员类,里面有4个方法。
定义了一个专门用于测试Marathonrunner运动员方法的类。如果我们想测试某个类,只需在那个类上添加@RuningTest注解,不加@RuningTest注解的方法不会进行测试。test5km()和test21km()方法都加了@RuningTest注解,所以被测试到。
注解在spring,mybatis注解中广发应用。下次专门写篇文章讲下spring中注解的应用。
总结:
本文主要讲解了注解的概念,元注解的概念,如何自定义注解,以及如何使用自己定义注解进行单元测试。
相关推荐
- 程序员:JDK的安装与配置(完整版)_jdk的安装方法
-
对于Java程序员来说,jdk是必不陌生的一个词。但怎么安装配置jdk,对新手来说确实头疼的一件事情。我这里以jdk10为例,详细的说明讲解了jdk的安装和配置,如果有不明白的小伙伴可以评论区留言哦下...
- Linux中安装jdk并配置环境变量_linux jdk安装教程及环境变量配置
-
一、通过连接工具登录到Linux(我这里使用的Centos7.6版本)服务器连接工具有很多我就不一一介绍了今天使用比较常用的XShell工具登录成功如下:二、上传jdk安装包到Linux服务器jdk...
- 麒麟系统安装JAVA JDK教程_麒麟系统配置jdk
-
检查检查系统是否自带java在麒麟系统桌面空白处,右键“在终端打开”,打开shell对话框输入:java–version查看是否自带java及版本如图所示,系统自带OpenJDK,要先卸载自带JDK...
- 学习笔记-Linux JDK - 安装&配置
-
前提条件#检查是否存在JDKrpm-qa|grepjava#删除现存JDKyum-yremovejava*安装OracleJDK不分系统#进入安装文件目...
- Linux新手入门系列:Linux下jdk安装配置
-
本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...
- 测试员必备:Linux下安装JDK 1.8你必须知道的那些事
-
1.简介在Oracle收购Sun后,Java的一系列产品就被整合到Oracle官网中,打开官网乍眼一看也不知道去哪里下载,还得一个一个的摸索尝试,而且网上大多数都是一些Oracle收购Sun前,或者就...
- Linux 下安装JDK17_linux 安装jdk1.8 yum
-
一、安装环境操作系统:JDK版本:17二、安装步骤第一步:下载安装包下载Linux环境下的jdk1.8,请去官网(https://www.oracle.com/java/technologies/do...
- 在Ubuntu系统中安装JDK 17并配置环境变量教程
-
在Ubuntu系统上安装JDK17并配置环境变量是Java开发环境搭建的重要步骤。JDK17是Oracle提供的长期支持版本,广泛用于开发Java应用程序。以下是详细的步骤,帮助你在Ubuntu系...
- 如何在 Linux 上安装 Java_linux安装java的步骤
-
在桌面上拥抱Java应用程序,然后在所有桌面上运行它们。--SethKenlon(作者)无论你运行的是哪种操作系统,通常都有几种安装应用程序的方法。有时你可能会在应用程序商店中找到一个应用程序...
- Windows和Linux环境下的JDK安装教程
-
JavaDevelopmentKit(简称JDK),是Java开发的核心工具包,提供了Java应用程序的编译、运行和开发所需的各类工具和类库。它包括了JRE(JavaRuntimeEnviro...
- linux安装jdk_linux安装jdk软连接
-
JDK是啥就不用多介绍了哈,外行的人也不会进来看我的博文。依然记得读大学那会,第一次实验课就是在机房安装jdk,编写HelloWorld程序。时光飞逝啊,一下过了十多年了,挣了不少钱,买了跑车,娶了富...
- linux安装jdk,全局配置,不同用户不同jdk
-
jdk1.8安装包链接:https://pan.baidu.com/s/14qBrh6ZpLK04QS8ogCepwg提取码:09zs上传文件解压tar-zxvfjdk-8u152-linux-...
- 运维大神教你在linux下安装jdk8_linux安装jdk1.7
-
1.到官网下载适合自己机器的版本。楼主下载的是jdk-8u66-linux-i586.tar.gzhttp://www.oracle.com/technetwork/java/javase/downl...
- window和linux安装JDK1.8_linux 安装jdk1.8.tar
-
Windows安装JDK1.8的步骤:步骤1:下载JDK打开浏览器,找到JDK下载页面https://d.injdk.cn/download/oraclejdk/8在页面中找到并点击“下载...
- 最全的linux下安装JavaJDK的教程(图文详解)不会安装你来打我?
-
默认已经有了linux服务器,且有root账号首先检查一下是否已经安装过java的jdk任意位置输入命令:whichjava像我这个已经安装过了,就会提示在哪个位置,你的肯定是找不到。一般我们在...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle忘记用户名密码 (59)
- oracle11gr2安装教程 (55)
- mybatis调用oracle存储过程 (67)
- oracle spool的用法 (57)
- oracle asm 磁盘管理 (67)
- 前端 设计模式 (64)
- 前端面试vue (56)
- linux格式化 (55)
- linux图形界面 (62)
- linux文件压缩 (75)
- Linux设置权限 (53)
- linux服务器配置 (62)
- mysql安装linux (71)
- linux启动命令 (59)
- 查看linux磁盘 (72)
- linux用户组 (74)
- linux多线程 (70)
- linux设备驱动 (53)
- linux自启动 (59)
- linux网络命令 (55)
- linux传文件 (60)
- linux打包文件 (58)
- linux查看数据库 (61)
- linux获取ip (64)
- linux进程通信 (63)