热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java开发_Java注解开发及原理

现在的Spring项目开发中,越来越多的都是由原先基于xml等配置开发,转成了基于注解开发。原先所有的内容都配置在.xml文件上,在Jav

现在的Spring项目开发中,越来越多的都是由原先基于xml等配置开发,转成了基于注解开发。原先所有的内容都配置在.xml文件上,在Java文件和配置文件来回转换,是相当麻烦和耗时的。为了解决这些个问题,Spring引入了注解,通过”@注解名称”的方式,让注解与Java Bean紧密结合,既大大减少了配置文件的体积,又增加了Java Bean的可读性与内聚性。今天就分享下,Java注解开发的原理。

元注解

先来看下如何定义一个注解,Jdk1.5提供给开发者四种元注解:@Retention、@Inherited、@Documented、@Target,jdk1.8又补充的2种@Repeatable、@Native注解,目的是为了让开发者可以通过元注解自定义注解,使用注解开发。下面对元注解进行介绍。

ae8e7dbeb5acd52d70e6db52946bb3d2.png

@Retention

注解的保留位置(枚举RetentionPolicy),RetentionPolicy可选值:

  • SOURCE:注解仅存在于源码中,在class字节码文件中不包含
  • CLASS:默认的保留策略,注解在class字节码文件中存在,但运行时无法获得
  • RUNTIME:注解在class字节码文件中存在,在运行时可以通过反射获取到

如下图,可以看到使用RetentionPolicy.SOURCE仅存在源码中

a65fe6cb3f1948bd0d37ff24ca6602f2.png

如下图,使用RetentionPolicy.CLASS,class文件也存在,运行期无法获取

f5fec081373cfd9f3f468fea3e41f640.png

没有获取到注解

06c9fc8411def56d138a1d6af2c910bf.png

如下图,使用RetentionPolicy.RUNTIME,class文件也存在,运行期可以获取

182c27dbed514cbd9b09f14072aba40c.png
4d48baf67a2e5287bdec948d1c48bb5b.png

@Inherited

声明子类可以继承此注解,如果一个类A使用此注解,则类A的子类也继承此注解

未使用@Inherited注解,子类无法基础注解

6ea15557b893b8a9f9841a1531707eb9.png
0aa6f66a4f4a8aee9e7e3eb8ae37fbc2.png

使用@Inherited注解后,子类则继承注解

f9a5535febf4d8fa148b63c5de8783c9.png
9ecf713a79fa2b5ff7010a24307ce902.png

@Documented

声明注解能够被javadoc等识别。

未使用@Documented注解,通过idea查看Javadoc,快捷键(ctrl + Q),发现注解并没有

21bb7a064c64394acb34956133baa292.png

使用@Documented注解,则doc文档中含有注解

f03c868edb9ef28a4701e1d0440f7fe0.png

@Target

用来声明注解范围(枚举ElementType),ElementType可选值:

  • TYPE:可以使用在接口、类、枚举、注解上
  • FIELD:可以使用在字段、枚举的常量中
  • METHOD:可以使用在方法上
  • PARAMETER:可以使用在方法参数上
  • CONSTRUCTOR:可以使用在构造函数中
  • LOCAL_VARIABLE:可以使用在局部变量中
  • ANNOTATION_TYPE:可以使用在注解中
  • PACKAGE:可以使用在package-info.java的包上
  • TYPE_PARAMETER:jdk1.8中新增,表示该注解能使用在自定义类型参数(参数的自定义类型可以是javaBean或者枚举等)的声明语句中
  • TYPE_USE:jdk1.8中新增,表示该注解能使用在使用类型的任意语句中

如下图,定义为ElementType.TYPE,则只能修饰类,不能修饰方法

5c6c5b7ad787afb11bbb4927b8231dbb.png

@Repeatable

@Repeatable注解即可以在同一方法、属性、类等类型中多次使用同一个注解。此特性相当于对Java8之前的重复注解在编译层面的增强

没有使用@Repeatable注解的时候写法

04ba3e3836d282b0abe1765e4f1042ea.png

使用@Repeatable注解的时候写法

fc8ef111b69617ca748401d9c836208b.png

@Native

该注解修饰成员变量,则表示这个变量可以被本地代码引用,常常被代码生成工具使用。对于 @Native 注解不常使用,了解即可

注解开发原理

注解的本质就是一个继承了 Annotation 接口的接口。我们可以去反编译任意一个注解类,可以通过字节码文件看到确实实现了Annotation接口

a8ca44122dfab63f95c57969110381f7.png

注解只不过是一种特殊的注释而已,如果没有解析它的代码,它可能连注释都不如。因此注解解析是非常重要的,而解析一个类或者方法的注解往往有两种形式,一种是编译期直接的扫描,一种是运行期反射。

编译器的扫描指的是编译器在对 java 代码编译字节码的过程中会检测到某个类或者方法被一些注解修饰,这时它就会对于这些注解进行某些处理。jdk中典型的就是注解 @Override,一旦编译器检测到某个方法被修饰了 @Override 注解,编译器就会检查当前方法的方法签名是否真正重写了父类的某个方法,也就是比较父类中是否具有一个同样的方法签名。这一种情况只适用于那些编译器已经熟知的注解类,比如 JDK 内置的几个注解,而你自定义的注解,编译器是不知道你这个注解的作用的,当然也不知道该如何处理,往往只是会根据该注解的作用范围来选择是否编译进字节码文件,仅此而已。

因此对于自定义接口,常常我们是通过运行期反射获取,代码如下

8f8b6eed46a2a24f61d4336db3e47943.png

运行期间,可以获取注解,以及注解的属性

c6ae4abbee8c8cee9903d71038c30065.png

一旦当我们获取到相应的注解及属性,可以执行一些特有的逻辑,从而实现注解的真正的意义。



推荐阅读
  • Java如何导入和导出Excel文件的方法和步骤详解
    本文详细介绍了在SpringBoot中使用Java导入和导出Excel文件的方法和步骤,包括添加操作Excel的依赖、自定义注解等。文章还提供了示例代码,并将代码上传至GitHub供访问。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文概述了JNI的原理以及常用方法。JNI提供了一种Java字节码调用C/C++的解决方案,但引用类型不能直接在Native层使用,需要进行类型转化。多维数组(包括二维数组)都是引用类型,需要使用jobjectArray类型来存取其值。此外,由于Java支持函数重载,根据函数名无法找到对应的JNI函数,因此介绍了JNI函数签名信息的解决方案。 ... [详细]
  • 本文介绍了Java调用Windows下某些程序的方法,包括调用可执行程序和批处理命令。针对Java不支持直接调用批处理文件的问题,提供了一种将批处理文件转换为可执行文件的解决方案。介绍了使用Quick Batch File Compiler将批处理脚本编译为EXE文件,并通过Java调用可执行文件的方法。详细介绍了编译和反编译的步骤,以及调用方法的示例代码。 ... [详细]
  • Mono为何能跨平台
    概念JIT编译(JITcompilation),运行时需要代码时,将Microsoft中间语言(MSIL)转换为机器码的编译。CLR(CommonLa ... [详细]
  • Annotation的大材小用
    为什么80%的码农都做不了架构师?最近在开发一些通用的excel数据导入的功能,由于涉及到导入的模块很多,所以开发了一个比较通用的e ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的步骤和方法
    本文介绍了在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的详细步骤和方法。首先需要下载最新的Java SE Development Kit 9发行版,然后按照给出的Shell命令行方式进行安装。详细的步骤和方法请参考正文内容。 ... [详细]
  • Google在I/O开发者大会详细介绍Android N系统的更新和安全性提升
    Google在2016年的I/O开发者大会上详细介绍了Android N系统的更新和安全性提升。Android N系统在安全方面支持无缝升级更新和修补漏洞,引入了基于文件的数据加密系统和移动版本的Chrome浏览器可以识别恶意网站等新的安全机制。在性能方面,Android N内置了先进的图形处理系统Vulkan,加入了JIT编译器以提高安装效率和减少应用程序的占用空间。此外,Android N还具有自动关闭长时间未使用的后台应用程序来释放系统资源的机制。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
author-avatar
任我闯2502871177
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有