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

您实际上对Java注释的理解程度如何?

如果您是Web或企业开发人员(大多数Java开发人员都是如此),则您始终会使用注释。无论是在Spring,JEE还是Struts中,您都会看到很多。如果您使用像JUnit这样的单元

如果您是Web或企业开发人员(大多数Java开发人员都是如此),则您始终会使用注释。 无论是在Spring,JEE还是Struts中,您都会看到很多。 如果您使用像JUnit这样的单元测试工具,则同样适用。 如果您进行胖客户端或Android开发,则在实际的生产代码中可能不会经常看到它,而您与它们的相遇可能是生产工具,构建工具和测试。 如果您使用上下文和依赖注入,那么注释就是您的主体。

当然,您要食用它们。 但是您知道如何做基本事情,例如如何定义一个吗? 也许你会。 但据我估计,在大多数情况下,如果您不开发API或部署工具,则可能很少需要定义注释。 我认为注释是Java语言元素,通常不完全理解。 也许我错了,但这只是我的意见。 我们为什么不从这里开始。


基本注释定义

请注意注释定义的语法,其中@interface表示类型。 这就是编译器识别注释类型的方式。 之所以使用这种语法,是因为注释类型基于与接口后面相同的管道。 还要注意方法声明。 您不会像在普通界面中那样实现这些功能。 编译器可以。 另外,(对于应用程序开发人员来说,) methods()都在使用时像字段一样对待。 通知Ln。 8.我们只说年龄= 33,就好像年龄是普通成员而不是方法。

尽管从源代码中看不出来,但是在Ln上使用了注释。 8保留程序不变。 回想一***释仅仅是元数据,它们不会改变程序的性质(至少不会直接改变)。 批注可以根据批注的类型向开发工具发出信号,以执行某些操作。 一个很好的例子就是Java EE的CDI引擎。 结果是,CDI运行时基于X注释提供了X,但是实际的源文件本身仍然没有改变。


还请参见:


注释类型的限制[1]



  • 注释不能参与继承。

  • 注释方法可能没有参数。

  • 注释不能通用,也不能指定throws子句。

  • 注释必须返回:枚举或原始类型或注释,String或Class对象。 他们还可以返回这些类型的数组。


默认注释

是在标准库和第三方提供程序中定义和使用的Java代码中使用的几个注释。

Java SE API [2]中定义的包java.lang提供了6个标准注释。 由于被包含在java.lang ,它们会自动导入每个Java程序中。 他们是:



  • @Deprecated —“注释为@Deprecated的程序元素是不鼓励程序员使用的元素。” [2]

  • @FunctionalInterface —“一种有用的注释类型,用于指示接口类型声明旨在成为Java语言规范定义的功能接口。” [2]

  • @Override —“表示方法声明旨在覆盖超类型中的方法声明。” [2]

  • @SafeVarags —“程序员断言,带注释的方法或构造函数的主体不会对其varargs参数执行潜在的不安全操作。” [2]

  • @SupressWarnings —“指示应在带注释的元素(以及带注释的元素中包含的所有程序元素)中禁止命名的编译器警告。” [2]

Java SE API [2]中定义的java.lang.annotation包提供6个标准注释。 他们是:



  • @Documented —“如果注释类型为A的声明中存在注释@Documented ,则元素上的任何@A注释都将被视为该元素的公共合同的一部分。” [2]用于标记另一个注释。

  • @Inherited —“指示注释类型是自动继承的。” [2]用于标记另一个注释。

  • @Native —“表示可以从本机代码中引用定义常量值的字段。” [2]

  • @Repeatable —“注释类型java.lang.annotation.Repeatable用于指示其声明(元-)注释的注释类型是可重复的。” [2]用于标记另一个注释。

  • @Retention —“指示带注释类型的注释将保留多长时间。” [2]用于标记另一个注释。

  • @Target- “指示注释类型适用的上下文。” [2]用于标记另一个注释。

我将不深入介绍这些注释。 但是,它们是标准Java SE开发中常见的注释。


还请参见:


单成员注释,默认值

简而言之,单成员注释是仅包含一个成员的注释。 该单个成员必须命名为value() 注意,如何使用注释中的括号(类似于方法参数)来分配值。

使用默认值

注意两件事。 首先是因为occupation()具有默认值,所以在第一个示例中,当使用@SampleAnnotation批注时,我们无需为其指定值。 在第二个示例中,请注意,因为根本不需要指定值。


还请参见:


保留政策

保留策略是使用注释时要理解的关键概念。 共有三种保留策略:CLASS,RUNTIME和SOURCE。 [2]它们在java.lang.annotation.RetentionPolicy中定义。 批注保留策略指定批注将保留多长时间。 它们使用@Retention批注指定。 默认保留策略是CLASS。 它们如下:



  • CLASS: “注释由编译器记录在类文件中,但VM在运行时无需保留。” [2]

  • RUNTIME: “注释将由编译器记录在类文件中,并在运行时由VM保留,因此可以以反射方式读取它们。” [2]

  • 消息来源: “注释将由编译器丢弃。” [2]

一个例子

一些读者可能会立即注意到,注释一直保留到运行时的能力允许使用Reflection使用数据。 这是注释有用的关键能力。 接下来,我们将简要介绍这一点。 另请注意,有关局部变量声明 (未初始化的变量,仅是声明)的注释未保留在Java字节码(.class文件)中。


还请参见:


运行时的注释信息-反射

正如我们刚刚谈到的那样,可以在运行时通过使用反射获得批注数据。 尽管我们不会讨论使用此功能的全部范围,但我将提供一个简短的示例来演示其用法。 尽管我们没有使用它,但AnnotatedElement接口提供了一些有用的方法来在运行时对Annotations进行反射。 最后,我没有直接使用java.lang.reflect AnnotatedElementField (Ln.7,8)。

编码

输出


还请参见:

我们所做的是:



  1. 我们做了三个注释。 SampleAnnotation以及名为SampleAnnotationContainer的容器注释(用于SampleAnnotation的重复实例)和SampleAnnotation2。 我们在SampleAnnotation的目标及其容器Annotation中指定了ElementType类型的值数组。 我们创建了RUNTIME批注。

  2. 我们创建了一个名为Annotate的类,并对该类以及该类的默认构造函数,main方法和该类中的字段进行了注释。 仅使用main()方法的SampleAnnotation2注释了一个元素。

  3. main()方法内部,我们实例化了封闭类的一个对象以用作反射的基础,并实例化了一个类型为Annotation的数组来保存注释。

  4. 我们进行了五次尝试以获得注释。 前四个通用步骤是使用Class API在特定元素上的注释实例化Annotation类型的数组。

  5. 有很多方法可以做到,但是我们做到了如下:

    1. 创建一个我们感兴趣的类的对象。

    2. 调用Object.getClass()获得Class <>对象,我们可以使用该对象执行反射。

    3. 调用getConstructor()getMethod()getField() ,以获取对要用来执行反射的元素的更具体的引用。 第一次尝试反射的步骤已跳过,该步骤在类本身上。

    4. 在返回的对象上调用Class.getAnnotations()方法以获取该对象的注释,并将该值分配给Annotation []类型的变量。

    5. 如有必要,我们处理了异常。

    6. 我们进行了一些格式化,并遍历了注释类型的数组并打印了元素。



  6. 我们使用了注释类型本身的引用来进行反射。 这是对SampleAnnotation2的引用。 我们使用与上述相同的方法实例化SampleAnnotation2的实例,除了我们调用getAnnotation(SampleAnnotation2.class)而不是getAnnotations() 为了打印内容,我们调用了Annotation的方法id() 因为当我们在id()上调用类型为SampleAnnotation2的对象时使用注释时,我们没有为id()指定值,所以它返回默认值,即字符串“ Default ID#43216”。


还请参见:


注释可以做的其他事情

注释还可以做其他事情,尽管我们在这里不进行深入讨论,但值得一提的是它们,以便您可以自己发现它们。

正如@Repeatable注释的存在所暗示的@Repeatable ,可以重复注释。 例如:

这些步骤实质上是:



  1. 创建注释以重复。

  2. 使用@Repeatable(x.class)标记要重复的注释,其中x是一个容器,用于保存要重复的注释的实例。

  3. 创建用于保存可重复注释实例的容器。

  4. 创建要重复的批注的数组,并将其命名为value() 它必须包含一个专门命名为value()

  5. 向您的心注解。

  6. 在容器注释上调用getAnnotation()以获取注释的实例,而不是在原始注释本身上调用getAnnotation()

如前所述,从JDK 8开始,可以注释类型。 此概念称为类型注释。

类型注释的定义中必须包含“ @Target (ElementType.TYPE_USE) ”,以便编译器将其理解为类型注释。 类型注释在将编译器插件用于源代码工具,构建工具和开发工具时非常有用。 我在下面讨论了更多有关此的内容,包括如何注释方法的接收者(隐含此参数)。

您还可以创建标记注释 标记注释只是没有任何成员的注释。 例如, @Override是标记注释。 它只是让代码的其他用户知道您正在重写超类方法。 例如,在创建的类中重写Object.toString()时。

API还有许多其他细微的功能和规则,例如您可能不会注释类型为void的方法返回类型。 我将它留给您进行发现。

已经知道所有这些东西了吗? 在下面的评论中告诉我您的经历:)


还请参见:

参考文献

[1] — Java:《完全参考》,第9版; 希尔德·希尔尔德·希尔尔德

[2] —Java®平台,标准版和Java开发套件版本9 API规范


This article was originally published on Noteworthy.


翻译自: https://jaxenter.com/understand-annotations-java-148001.html




推荐阅读
  • 在Java Web服务开发中,Apache CXF 和 Axis2 是两个广泛使用的框架。CXF 由于其与 Spring 框架的无缝集成能力,以及更简便的部署方式,成为了许多开发者的首选。本文将详细介绍如何使用 CXF 框架进行 Web 服务的开发,包括环境搭建、服务发布和客户端调用等关键步骤,为开发者提供一个全面的实践指南。 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 本文深入解析了Java面向对象编程的核心概念及其应用,重点探讨了面向对象的三大特性:封装、继承和多态。封装确保了数据的安全性和代码的可维护性;继承支持代码的重用和扩展;多态则增强了程序的灵活性和可扩展性。通过具体示例,文章详细阐述了这些特性在实际开发中的应用和优势。 ... [详细]
  • 在本文中,我们将为 HelloWorld 项目添加视图组件,以确保控制器返回的视图路径能够正确映射到指定页面。这一步骤将为后续的测试和开发奠定基础。首先,我们将介绍如何配置视图解析器,以便 SpringMVC 能够识别并渲染相应的视图文件。 ... [详细]
  • 在使用SSH框架进行项目开发时,经常会遇到一些常见的问题。例如,在Spring配置文件中配置AOP事务声明后,进行单元测试时可能会出现“No Hibernate Session bound to thread”的错误。本文将详细探讨这一问题的原因,并提供有效的解决方案,帮助开发者顺利解决此类问题。 ... [详细]
  • 本文详细解析了Java类加载系统的父子委托机制。在Java程序中,.java源代码文件编译后会生成对应的.class字节码文件,这些字节码文件需要通过类加载器(ClassLoader)进行加载。ClassLoader采用双亲委派模型,确保类的加载过程既高效又安全,避免了类的重复加载和潜在的安全风险。该机制在Java虚拟机中扮演着至关重要的角色,确保了类加载的一致性和可靠性。 ... [详细]
  • Python 序列图分割与可视化编程入门教程
    本文介绍了如何使用 Python 进行序列图的快速分割与可视化。通过一个实际案例,详细展示了从需求分析到代码实现的全过程。具体包括如何读取序列图数据、应用分割算法以及利用可视化库生成直观的图表,帮助非编程背景的用户也能轻松上手。 ... [详细]
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • 在C++程序中,文档A的每一行包含一个结构体数据,其中某些字段可能包含不同数量的数字。需要将这些结构体数据逐行读取并存储到向量中,随后不仅在控制台上显示,还要输出到新创建的文档B中。希望得到指导,感谢! ... [详细]
  • 在使用 Qt 进行 YUV420 图像渲染时,由于 Qt 本身不支持直接绘制 YUV 数据,因此需要借助 QOpenGLWidget 和 OpenGL 技术来实现。通过继承 QOpenGLWidget 类并重写其绘图方法,可以利用 GPU 的高效渲染能力,实现高质量的 YUV420 图像显示。此外,这种方法还能显著提高图像处理的性能和流畅性。 ... [详细]
  • 深入理解Java中的多态性概念及其应用
    多态是面向对象编程中的三大核心特性之一,与封装和继承共同构成了面向对象的基础。多态使得代码更加灵活和可扩展,封装和继承则为其提供了必要的支持。本文将深入探讨多态的概念及其在Java中的具体应用,帮助读者全面理解和掌握这一关键知识点。 ... [详细]
  • 分享一款基于Java开发的经典贪吃蛇游戏实现
    本文介绍了一款使用Java语言开发的经典贪吃蛇游戏的实现。游戏主要由两个核心类组成:`GameFrame` 和 `GamePanel`。`GameFrame` 类负责设置游戏窗口的标题、关闭按钮以及是否允许调整窗口大小,并初始化数据模型以支持绘制操作。`GamePanel` 类则负责管理游戏中的蛇和苹果的逻辑与渲染,确保游戏的流畅运行和良好的用户体验。 ... [详细]
  • 枚举类中enum关键字的常见应用与实践
    在枚举类中,`enum`关键字具有重要的作用,本文探讨了其常见的应用场景与实践。特别指出,枚举对象必须置于枚举类的首行,否则将导致编译错误。通过具体的代码示例,详细解析了这一规则及其背后的原理,帮助开发者更好地理解和使用枚举类。 ... [详细]
  • Squaretest:自动生成功能测试代码的高效插件
    本文将介绍一款名为Squaretest的高效插件,该工具能够自动生成功能测试代码。使用这款插件的主要原因是公司近期加强了代码质量的管控,对各项目进行了严格的单元测试评估。Squaretest不仅提高了测试代码的生成效率,还显著提升了代码的质量和可靠性。 ... [详细]
author-avatar
手机用户2502927925
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有