注解简介

所谓注解,其实就像一种拥有特定作用的注释,自 JDK1.5 及之后版本所引入的特性,它是放在 Java 源码的类、方法、字段、参数前的一种用作标注的“元数据”,与类、接口、枚举处于同一个层次中。

通过其作用的不同,我们常常将注解分为如下 3 类:

  1. 编写文档:通过代码中标识的注解生成对应文档(即类似于 Java doc 的文档);
  2. 代码分析:通过代码中标识的注解对代码进行分析(使用反射);
  3. 编译检查:通过代码中标识的注解让编译器能实现基本的编译检查(@Override);

常用的预定义注解

@Override

一般是用在方法上,表示重写该父类的方法,比如我们使用最多的 toString() 方法,它是 Object 类的一个方法,而我们的写的类都是继承自 Object 类,所以我们自定义的所有类都是有 toString() 方法的。但是如果我们自定义类中的方法在父类中没有,则不能使用该注解,否则会导致无法编译通过。

package com.cunyu;/*** Created with IntelliJ IDEA.** @author : cunyu* @version : 1.0* @email : 747731461@qq.com* @website : https://cunyu1943.github.io* @date : 2021/6/20 10:04* @project : JavaWeb* @package : com.cunyu* @className : OverrideTest* @description :*/public class OverrideTest {private Integer id;private String name;public OverrideTest(Integer id, String name) {this.id = id;this.name = name;}@Overridepublic String toString() {final StringBuffer sb = new StringBuffer("OverrideTest{");sb.append("id=").append(id);sb.append(", name='").append(name).append('\'');sb.append('}');return sb.toString();}public static void main(String[] args) {Integer id = 101;String name = "村雨遥";OverrideTest overrideTest = new OverrideTest(id, name);System.out.println(overrideTest);}
}

@Deprecated

一般用在方法之前,表示该方法已经过期,不建议再继续使用(但是仍然有效,只不过可能有更新的版本,推荐使用更新的版本)。

package com.cunyu;/*** Created with IntelliJ IDEA.** @author : cunyu* @version : 1.0* @email : 747731461@qq.com* @website : https://cunyu1943.github.io* @公众号 : 村雨遥* @date : 2021/6/20 10:07* @project : JavaWeb* @package : com.cunyu* @className : DeprecateTest* @description :*/public class DeprecateTest {@Deprecatedpublic static void sayHello() {System.out.println("Hello World!");}public static void newSayHello() {System.out.println("Hello,Welcome to Java !");}public static void main(String[] args) {sayHello();newSayHello();}
}

@SuppressWarnings

表示忽略警告信息,常用的值以及含义如下表:

描述
deprecation 使用了不赞成使用的类或方法时的警告
unchecked 使用了未经检查的转换时的警告
fallthrough switch 程序块直接通往下一种情况而没有 break 时的警告
path 在类路径、源文件路径等中有不存在的路径时的警告
serial 当在可序列化的类上缺少 serialVersionUID 定义时的警告
finally 任何 finally 子句不能正常完成时的警告
rawtypes 泛型类型未指明
unused 引用定义了,但是没有被使用
all 关闭以上所有情况的警告
package com.cunyu;import java.util.ArrayList;
import java.util.List;/*** Created with IntelliJ IDEA.** @author : cunyu* @version : 1.0* @email : 747731461@qq.com* @website : https://cunyu1943.github.io* @公众号 : 村雨遥* @date : 2021/6/20 10:07* @project : JavaWeb* @package : com.cunyu* @className : SuppressWarningsTest* @description :*/public class SuppressWarningsTest {@SuppressWarnings("unchecked")public static void main(String[] args) {String item = "村雨遥";@SuppressWarnings("rawtypes")List items = new ArrayList();items.add(item);System.out.println(items);}
}

自定义注解

格式

我们可以使用 @interface 来自定义注解,其格式如下:

public @interface AnnotationName{// 属性列表……
}

一个简单的示例如下,其中 AnnoDemo 代表着我们自定义注解的名称,而 name()age()score() 则分别表示自定义注解的三个属性,而且我们利用关键字 default 对每个属性都赋予了默认值。

public @interface AnnoDemo{String name() default "村雨遥";int age() default 20;float score() default 60.0f;
}

原理

注解本质上相当于一个接口,它默认继承自 java.lang.annotation.Annotation

public interface AnnotationName extends java.lang.annotation.Annotation{}

参数

注解的参数类似于无参的方法,通常我们推荐用 default 来设定一个默认值,对于方法的基本要求通常有如下几点:

  1. 方法的返回值类型不可以是 void
  2. 如果定义了方法,那么在使用时需要给方法进行赋值,赋值的规则如下:
    1. 若定义方法时,使用了关键字 default 对方法赋予了默认初始值,那么在使用注解时,可以不用对方法进行再次赋值;
    2. 若只有一个方法需要赋值,且方法名为 value,那么此时 value 可以省略,直接定义值即可;
    3. 数组赋值时,值需要用大括号 {} 包裹,若数组中只有一个值,那么此时 {} 可以省略;
public @interface AnnoDemo{String name() default "村雨遥";int age() default 20;float score() default 60.0f;
}

如上述例子中,name()age()score() 就是我们自定义注解的参数。而当我们要是用该注解时,则通过如下方式来对参数进行赋值。

@AnnoDemo(name = "村雨遥", age = 26, score = 95.0f)
public class Demo{……
}

元注解

定义

所谓元注解(meta annotation),就是可以用来修饰其他注解的注解。

常用的元注解

  1. @Target

描述注解所修饰的对象范围,其取值主要有如下几种:

说明
ElementType.TYPE 表示可以作用于类或接口
ElementType.FIELD 表示可以作用于成员变量
ElementType.METHOD 表示可以作用于方法
ElementType.CONSTRUCTOR 表示可以作用于构造方法
ElementType.PARAMETER 表示可以作用于方法的参数
@Target(ElementType.TYPE)
public @interface AnnoDemo{String name() default "村雨遥";int age() default 20;float score() default 60.0f;
}
  1. @Retention

用于约束注解的生命周期,其取值如下:

说明
RetentionPolicy.SOURCE 表示在源代码文件中有效,注解将被编译器丢弃(注解信息仅保留在源码中,源码经编译后注解信息丢失,不再保留到字节码文件中)
RetentionPolicy.CLASS 表示在字节码文件中有效,注解在字节码文件中可用,但会被 JVM 丢弃
RetentionPolicy.RUNTIME 表示在运行时有效,此时可以通过反射机制来读取注解的信息
@Target(ElementType.TYPE)
@Retention(RetentionPoicy.RUNTIME)
public @interface AnnoDemo{String name() default "村雨遥";int age() default 20;float score() default 60.0f;
}
  1. @Documented

描述其他类型的注解是否被抽取到 API 文档中。

@Target(ElementType.TYPE)
@Retention(RetentionPoicy.RUNTIME)
@Documented
public @interface AnnoDemo{String name() default "村雨遥";int age() default 20;float score() default 60.0f;
}
  1. @Inherited

这是一个标记注解,描述某个注解能够被子类继承,但是该元注解只适合已经配置了 @Target(ElementType.TYPE) 类型的自定义注解,而且仅针对于类的继承,而对于接口的继承则无效。

@Inherited
public @interface AnnoDemo{String name() default "村雨遥";int age() default 20;float score() default 60.0f;
}
  1. @Repeatable

该注解是从 JDK1.8 新引入的元注解,表示在同一位置能够重复相同的注解。在没有该注解之前,我们一般是无法在同一类型上使用相同注解的,但引入该注解后,我们就可以在同一类型上使用相同注解。

@Target(ElementType.TYPE)
@Repeatable(AnnoDemos.class)
public @interface AnnoDemo{String name() default "村雨遥";int age() default 20;float score() default 60.0f;
}public @interface AnnoDemos{AnnoDemo[] value();
}

利用 @Repeatable 配置自定义注解之后,我们就可以在某个类型声明处添加多个我们自定义的注解了。

@AnnoDemo(name = "村雨遥", age = 26, score = 88.0f)
@AnnoDemo(name = "晓瑜", age = 27, score = 90.0f)
public class Student{……
}

总结

总结上述的知识点,我们将自定义注解的过程归纳为如下 3 步。

  1. 定义一个注解
public @interface AnnoDemo{}
  1. 添加参数并设置默认值
public @interface AnnoDemo{String name() default "村雨遥";int age() default 20;float score() default 60.0f;
}
  1. 利用元注解来配置我们的自定义注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnoDemo{String name() default "村雨遥";int age() default 20;float score() default 60.0f;
}

在实际应用过程中,利用元注解配置自定义注解时,必须设置 @Target@Retention 两个元注解,而且 @Retention 的值通常是设置为 RetentionPolicy.RUNTIME

好了,以上就是我们注解的相关概念以及自定义注解所需要的掌握的一些知识点了,如果你觉得对你有所帮助,那就来一波点赞关注吧!

Java 菜鸟入门 | 深入浅出 Java 注解相关推荐

  1. C功底挑战Java菜鸟入门概念干货(一)

    一.认识Java 1.Java 程序比较特殊,它必须先经过编译,然后再利用解释的方式来运行.  2.Byte-codes 最大的好处是--可越平台运行,可让"一次编写,处处运行"成 ...

  2. Java高级篇——深入浅出Java类加载机制

    转载自 Java高级篇--深入浅出Java类加载机制 类加载器 简单讲,类加载器ClassLoader的功能就是负责将class文件加载到jvm内存. 类加载器分类 从虚拟机层面讲分为两大类型的类加载 ...

  3. 菜鸟入门:Java程序员学习之路

     1. Java语言基础 谈到Java语言基础学习的书籍,大家肯定会推荐Bruce Eckel的<Thinking in Java>.它是一本写的相当深刻的技术书籍,Java语言基础部分基 ...

  4. java annotation入门_JAVA - Annotation 注解 入门

    Java注解提供了关于代码的一些信息,但并不直接作用于它所注解的代码内容.在这个教程当中,我们将学习Java的注解,如何定制注解,注解的使用以及如何通过反射解析注解. Java1.5引入了注解,当前许 ...

  5. java查询日期类的表,JAVA菜鸟入门篇 - 时间处理相关类实例:打印该月日期表 (29)...

    利用前面我们所学习有关时间处理类,Date.DateFormat.SimpleDateFormat以及Calendar和GregorianCalendar类 编写一个按照用户定义格式(格式:2015- ...

  6. Java程序入门教程 | Java

    有一个朋友这样告诉我:Java太难了!上课老师不讲代码,我怎么学?! 我也发现了,以我们学校为例吧.很多Java教学者似乎不太愿意细嗦代码怎么写.(在大一已经学习过C语言的基础上,Java其实真的很简 ...

  7. 虚拟机 java 开发_深入浅出 Java 虚拟机 · 通往高级 Java 开发的必经之路

    第一章 JVM 内存模型 Java 虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是:程序计数器 Java 虚拟机栈 本地方法栈 堆 方法区. 下面对这五个区域 ...

  8. JAVA基础入门教程——Java介绍

    1. Java简介 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称,目前由Oracle拥有. Java可运行于多个平台,如Win ...

  9. 【Java菜鸟 04】Java中的File类详解

    Java.io.File类主要是完成了文件夹管理的命名.查询文件属性和处理目录等操作,它不进行文件夹内容的读取操作. 1.构造函数: File file = new File(inputPath); ...

最新文章

  1. Spring定时任务的几种实现
  2. delphi中,idftp怎样查找ftp服务器的是否存在一个文件,delphi – IDFTP DirExists和MakeDir...
  3. 程序运行依赖的重要文件版本不对_Deno核心模块:灵活依赖amp;安全沙箱
  4. 使用layui的layer组件做弹出层
  5. oracle 对两列加唯一性束_oracle中创建unique唯一约束(单列和多列) 。
  6. linux查看php命令目录权限,PHP执行linux命令mkdir权限问题
  7. Rust创建项目的两种方式
  8. UITableView优化之按需加载
  9. HDU2516 取石子游戏
  10. 有没有在学习IT营2020年新出Go语言视频教程童鞋,一起探讨
  11. bpsk在瑞利信道matlab,请教BPSK在瑞利信道下的误码率仿真
  12. ajax有哪些回调函数
  13. 如何使用GoldWave中文版将语音转化为文字
  14. SOLD2算法详解之1 backbone(CVPR2021 源码解析)
  15. 读计算机网络得学五笔吗,新手学五笔打字的步骤
  16. Arduino循迹小车教程一----材料篇
  17. 两个天才黑客:一人在牢狱之灾后退隐江湖,一人蜕变成阿里巴巴“守护神”!...
  18. Smart3D初学者第二步:三维模型重建(1)
  19. 堪称完美,仅用了330页直接封神,被大家吹爆的RocketMQ笔记
  20. 欧盟立法者为ICO重新制定“标准”

热门文章

  1. 汇编语言逻辑“或”指令与应用示例:OR (Logical Inclusive OR)和 XOR (Logical Exclusive OR)
  2. 汇编语言 AND逻辑与指令
  3. BTC-Relay与RootStock侧链技术对比
  4. 把项目从meeclipces转移到idead中遇见的问题
  5. 计算机二级是win7,计算机二级等考宝典
  6. OSG场景漫游(一)
  7. qq满屏飞吻代码_[爱情][飞吻][跳跳][爱心][嘴唇][玫瑰][月亮][礼物][拥抱]什么意思...
  8. EcShop开发手册
  9. git提交如何忽略某些文件
  10. 把电脑端的图片链接转换为API接口可以调用的链接