1、为何要使用注解?

在各种框架中,经常使用XML文件作为配置文件,从而实现框架中程序编写的解耦。但是随着开发的内容越来越复杂,对于框架中的所有对象进行XML配置将会使配置文件的维护成本急剧增加。

注解就是在这一条件下提出的解决方法,它依附于代码(类、方法以及属性)上,降低了配置时的维护成本,但是同时也增加了代码的耦合程度,所以现阶段框架中一般都支持XML配置文件和注解同时使用,在保证一定解耦的情况下,简化开发的过程。

2、注解的定义

(1)注解本质上就是继承了Annotation接口的一个接口。

(2)从注解的作用角度来说,注解也叫元数据,是一种描述数据的数据,主要用于对代码做出标识,从而对于标识过的代码进行一系列操作,它可以作用于包、类、接口、方法以及属性中。

(3)注解的组成部分:

定义注解的元注解

注解名称(@Interface 注解名)

注解属性(可有可无):注解只有属性,但是注解属性的定义方式是正常类的方法定义方式。

3、注解的分类与详解

Java中注解的继承体系如下:

从上图可知:一个Annotation接口会与多个ElementType枚举类和一个RetentionPolicy枚举类相关联。

ElementType枚举类,定义了注解要作用的位置,在@Target注解中经常使用:

public enum ElementType {

TYPE,//注解作用于类、接口和枚举上

FIELD,//注解作用于属性上

METHOD,//注解作用于方法上

PARAMETER,//注解作用于方法中的参数上

CONSTRUCTOR,//注解作用于构造器方法上

LOCAL_VARIABLE,//注解作用于局部变量上

ANNOTATION_TYPE,//注解作用于注解上

PACKAGE,//注解作用于一个包上

TYPE_PARAMETER,//注解作用于声明的变量上上

TYPE_USE,

MODULE//注解作用于一个模块上

}

RetentionPolicy枚举类,定义了注解作用的时间段,在@Retention注解中经常使用:

public enum RetentionPolicy {

SOURCE,//注解在编译器阶段失效

CLASS,//注解在运行时阶段失效

RUNTIME//注解在运行时还是会保留

}

而Java中的注解大致可分为三类:

元注解

Java自带注解

自定义注解

3.1、元注解

元注解即是用于定义其他注解的注解,在Java中共有五类:

3.1.1、@Target:定义注解作用的位置

(1)使用格式:

@Target(ElementType.(选择ElementType枚举类中的属性来决定注解作用的位置))

(2)可选属性及其含义,其实完全可以参照之上的ElementType枚举类的源代码,此处为了对应再次列出:

ElementType.TYPE:注解作用于类、接口和枚举上

ElementType.FIELD:注解作用于属性上

ElementType.METHOD:注解作用于方法上

ElementType. PARAMETER:注解作用于方法中的参数上

ElementType.CONSTRUCTOR:注解作用于构造器方法上

ElementType. LOCAL_VARIABLE:注解作用于局部变量上

ElementType.ANNOTATION_TYPE:注解作用于注解上

ElementType.PACKAGE:注解作用于一个包上

ElementType.TYPE_PARAMETER:注解作用于声明的变量上

ElementType.TYPE_USE:注解作用于一个使用的类型上

ElementType. MODULE:注解作用于一个模块上

(3)使用实例

这里,我们事先引入一个自定义的注解,只是为了演示@Target注解的使用方式,并不做过多说明,代码如下:

//该@Target注解说明,所定义的@MyAnno1注解可以作用于类、属性和方法上

@Target(value={ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})

//若作用范围只有一个可定义为:@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

@interface MyAnno1{

}

3.1.2、@Retention:定义注解所作用的时期

(1)使用格式

@Retention(RetentionPolicy.(RetentionPolicy枚举类中的属性))

(2)可选属性及其含义,其实完全可以参照之上的RetentionPolicy枚举类的源代码,此处为了对应再次列出:

RetentionPolicy.SOURCE:注解只保留在源代码阶段,在编译时就会失效;

RetentionPolicy.CLASS:注解只保留在Class对象阶段,不会进入JVM,在运行时会失效;

RetentionPolicy. RUNTIME:注解会进入JVM,在运行时会保留;

(3)使用实例:

@Target(value={ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})

//定义的注解@MyAnno1,在运行时还是存在并可以获取的

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

@interface MyAnno1{

}

3.1.3、@Documented:定义注解作用后是否会生成文档

该注解中并未定义任何要赋值的属性值,故只要该注解存在,即可以生成文档;不存在即不可生成文档。

3.1.4、@Inherit:注解所作用类被继承时,该注解是否会被继承

该注解中并未定义任何要赋值的属性值。故在定义注解时,只要@Inherit注解存在,则所定义的注解,在作用于一个类之后,该类被继承时,所定义的注解也会被继承;反之则不可被继承。

3.1.5、@Repeatable:注解是否可以在同一个作用点被使用多次

@Repeatable注解的使用步骤详解:

① 先定义一个含有要赋值的成员属性的自定义注解,其中成员属性的类型应该是一个自定义注解的类型。

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@interface Accounts {

//自定义注解中要赋值的成员属性

Account[] value();

}

② 对于@Accounts注解中成员属性类型的@Account注解进行定义,此处便要使用@Repeatable注解。

@Repeatable(Accounts.class)

@interface Account{

String bank() default "农业银行";

}

③ 以上定义步骤完成后,在类上使用@Account注解,使用实例如下:

@Account(bank="中国银行")

@Account(bank="工商银行")

@Account(bank="建设银行")

class CreateAccount{

String bank="";

}

以上三个步骤展示了使用@Repeatable注解定义其它注解的使用方法,以及被@Repeatable注解定义的注解的使用示例。

3.2、Java自带注解

对于Java中自带的注解,我们可以参照其源码进行理解,并掌握其所代表的含义即可。

3.2.1、@Override

注解源码:

@Target(ElementType.METHOD)//该注解作用于方法上

@Retention(RetentionPolicy.SOURCE)

public @interface Override {

}

注解作用:检查该方法是否是重写方法。

使用格式:直接使用

3.2.2、@Deprecated

注解源码:

@Documented

@Retention(RetentionPolicy.RUNTIME)

//该注解可作用于几乎所有代码上

@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})

public @interface Deprecated {

String since() default "";

boolean forRemoval() default false;

}

注解作用:标记过时代码。

使用格式:直接使用

3.2.3、@Deprecated

注解源码:

//该注解可作用于几乎所有代码上

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})

@Retention(RetentionPolicy.SOURCE)

public @interface SuppressWarnings {

//由于存在成员属性value,使用该注解时必须赋值

String[] value();

}

注解作用:指示编译器去忽略注解中声明的警告,注解中成员属性value所要赋予的值就是要忽略的警告的名称,如"deprecation", "unchecked"等。

使用格式:@SuppressWarnings (value={"deprecation", "unchecked"})

3.2.4、@FunctionalInterface

注解源码:

@Documented

@Retention(RetentionPolicy.RUNTIME)

//该注解作用于接口上

@Target(ElementType.TYPE)

public @interface FunctionalInterface {}

注解作用:用于限制一个接口是一个函数式接口。

使用格式:直接使用

3.2.5、@SafeVarargs

注解源码:

@Documented

@Retention(RetentionPolicy.RUNTIME)

//该注解作用于构造器方法和方法上

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})

public @interface SafeVarargs {}

注解作用:用于提醒开发者不要用参数做一些不安全的操作。

使用格式:直接使用

3.3、自定义注解

在之前,已经粗略探讨过注解的组成部分,主要分为三大块:元注解,注解名和注解属性,接下来就结合代码来解析如何自定义一个注解以及自定义注解后有什么用处。

① 首先,我们事先定义一个注解

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

/*-----以上为元注解---*/

@interface Check{//->注解名称

//此处未定义成员属性,若定义成员属性,

//格式为:成员属性类型 成员属性名称();

}

② 使用自定义的注解

public class AnnoUse {

//加法

@Check

public void add(){

String str = null;

str.toString();

System.out.println("1 + 0 =" + (1 + 0));

}

//减法

@Check

public void sub(){

System.out.println("1 - 0 =" + (1 - 0));

}

//乘法

@Check

public void mul(){

System.out.println("1 * 0 =" + (1 * 0));

}

//除法

@Check

public void div(){

System.out.println("1 / 0 =" + (1 / 0));

}

}

③使用了注解之后的操作

public static void main(String[] args) throws IOException {

//执行时,自动检测所有加了Check注解的方法

// 判断方法是否存在异常,记录到文件中

AnnoUse au=new AnnoUse();

//2.获取字节码文件对象

Class cls = au.getClass();

//3.获取所有方法

Method[] methods = cls.getMethods();

int number = 0;//出现异常的次数

BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));

for (Method method : methods) {

//4.判断方法上是否有Check注解

if(method.isAnnotationPresent(Check.class)){

//5.有,执行

try {

method.invoke(au);

} catch (Exception e) {

//6.捕获异常

//记录到文件中

number ++;

bw.write(method.getName()+ " 方法出异常了");

bw.newLine();

bw.write("异常的名称:" + e.getCause().getClass().getSimpleName());

bw.newLine();

bw.write("异常的原因:"+e.getCause().getMessage());

bw.newLine();

bw.write("--------------------------");

bw.newLine();

}

}

}

bw.write("本次测试一共出现 "+number+" 次异常");

bw.flush();

bw.close();

}

由以上流程,可以知道注解的自定义过程以及使用注解的意义。注解往往只是一种标识,需要和反射相结合才能从代码中选出相应的部分作出相应操作或获取相应信息,这也是注解被各个框架所广泛使用的原因。

4、总结

注解作为一种标记性的数据,在框架中作为反射时获取相应信息的选择器条件,在一定程度上从当了xml配置文件的作用。而现阶段使用框架时,往往需要将xml配置文件和注解相结合来简化开发,且注解因其简便性往往占据较大比重,故此需要深刻理解注解的底层原理并要灵活使用。在后期,可以结合框架来深入理解注解的妙用。

java 注解开发 解耦_Java提升七:注解相关推荐

  1. java注解和反射原理_Java中的注解和反射

    最近又回顾了一下 Java 中的注解和反射知识点,注解在日常开发中使用很多,但是反射比较少.值得注意的是 Java 的各种框架底层源码中大量使用了注解和反射,阅读源码,这些是基本功,面试中这部分内容也 ...

  2. java 注解默认值_Java系列之注解

    Java 注解(Annotation)又称之为 Java 标注.元数据,是 Java 1.5 之后加入的一种特殊语法,通过注解可以标注 Java 中的类.方法.属性.参数.包等,可以通过反射原理对这些 ...

  3. java opencv 开发环境_Java + opencv学习:在Eclipse下配置基于Java的OpenCV开发环境

    最近研究OpenCV想用java进行开发,因此研究了一下怎么在Eclipse中配置基于java的Opencv. 第一步:先到OpenCV官网下载你想要的版本,假设使用的是2.4.6版本.这里附上下载地 ...

  4. 注解报错_Java中的注解使用:全面性的总结一下

    前话: 今天,我们又来聊一下注解的使用,做一下详细的解析,也介绍了自定义注解,请耐心往下看哟! 注解的介绍: 在2005年,sun公司推出了jdk1.5,同时推出的注解功能吸引了很多人的目光,使用注解 ...

  5. java web开发技巧_java web开发技巧

    1 java web开发技巧 java学习没有诀窍,也没有捷径.只有脚踏实地学好java知识,把理论知识灵活运用实践,多学,多问,多操作,只要这样才能真正成为java编程高手.下面小编给大家说说jav ...

  6. java实验 输入输出流_java实验七 输入输出流

    有关java的实验和程序 实验七 输入输出流 一.实验目的和要求 目的: 1.掌握使用输入输出流进行文件的读写操作. 要求: 1.实验报告给出内容1,2的填充代码以及内容3的全部源代码. 二.实验内容 ...

  7. java的开发工具_Java中常用的开发工具有哪些

    Eclipse   据数据显示很多Java开发人员的Java开发工具便是Eclipse,这主要得益于Eclipse是一个开源的.可以基于Java的可扩展开发平台.Eclipse本身而言,它只是一个框架 ...

  8. java自定义监听器例子_Java使用自定义注解实现为事件源绑定事件监听器操作示例...

    本文实例讲述了Java使用自定义注解实现为事件源绑定事件监听器操作.分享给大家供大家参考,具体如下: 一 定义注解 import java.lang.annotation.*; import java ...

  9. java反射获得注释_Java反射、注解

    1.反射 案例: 需求:写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法 实现: 1.配置文件 2.反射 步骤: 1.将需要创建的对 ...

最新文章

  1. 重大里程碑!VOLO屠榜CV任务,无需额外数据,首次在ImageNet 上达到87.1%
  2. 自己构建一个高效缓存服务!
  3. wxWidgets:wxMoveEvent类用法
  4. ant design中的栅格化系统
  5. linux给命令起别名命令,alias命令 – 设置命令别名
  6. Html设置div重置样式,CSS 重置样式
  7. 125条常见的java面试笔试题大汇总1
  8. 使用python插件将程序打包为exe
  9. 全面剖析泛微协同管理平台(e-cology)十大亮点
  10. java网上订餐系统开题报告_基于WEB的网上订餐系统-开题报告.doc
  11. mysql分页limit (currentPage-1)*pageSize,pageSize
  12. CSP考试 2016年04月第3题 路径解析 C++实现
  13. 如何使用Google TV设置Chromecast
  14. vue + echarts 之饼形图
  15. challenges
  16. 10. 请至少列举5个 PEP8 规范(越多越好)。
  17. 林氏物语之春江花月.音乐随想系列之sleeping sun及诗经版译文
  18. Android WebView 安全漏洞
  19. Qt编写自定义控件22-蚂蚁线
  20. 热门软件看点:花季护航蹿红解读

热门文章

  1. oracle Client 11g静默安装
  2. 三元一次方程组步骤_姜红梅名师工作室【教学感悟】三元一次方程组解法的思考...
  3. 删除docker私服镜像脚本
  4. ImageIO 合并图片工具
  5. 基于JAVA+SpringMVC+MYSQL的营业厅终端销售系统
  6. kk服务器信息及端口,kk服务器设置
  7. H5页面移动端IOS键盘收起焦点错位
  8. 查看提交历史(git log)
  9. python入门三:文件操作
  10. HDU 2577 How to Type