前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java注释:您想知道的一切

Java注释:您想知道的一切

作者头像
用户7466307
发布2020-06-16 22:37:51
1.5K0
发布2020-06-16 22:37:51
举报

注释是元数据的一种形式。它提供有关程序的数据,该数据不属于程序本身。注释对其注释的代码的操作没有直接影响。注释是在Java语言规范的第三版中以Java语言首次引入的,并首先在Java 5中实现。

注释具有多种用途,其中包括:

  • 供编译器 ?使用的信息 - 编译器可以使用注释来检测错误或禁止显示警告。
  • 编译时和部署时处理 ?-软件工具可以处理注释信息以生成代码,XML文件等。
  • 运行时处理 ?-在运行时可以检查一些注释。

使用注释,我们能够将元数据信息添加到我们的源代码中-构建或部署信息,配置属性,编译行为或质量检查。

在这里,我将解释在何处可以使用批注,如何应用批注,Java平台标准版(Java SE API)中可用的预定义批注类型。

注释基础

注释总是出现在被注释的代码之前,并且按照惯例,通常在其自己的行中以相同的级别缩进。

注释可能适用于包,类型(类,接口,枚举和注释类型),变量(类,实例和局部变量-包括在for或while循环中定义的变量),构造函数,方法和参数。

以最简单的形式,注释如下所示:

代码语言:javascript
复制
@Entity

at符号字符(@)向编译器指示后面是注释。在以下示例中,注释的名称为Override:

代码语言:javascript
复制
@Override
void myAnnotationUsageMethod() { 
... 
}

批注可以包含可以命名或未命名的elements,并且这些元素具有值:

代码语言:javascript
复制
@Author(
   name = "Roland Hewage",
   date = "2019/04/18"
)
class MyClass() { ... }

例如,可以在以下方法中使用它们:

代码语言:javascript
复制
@SuppressWarnings(value = "unchecked")
void myMethod() { ... }

注释可能包含仅由逗号分隔的名称/值对的元素。允许的类型是这些类型的原语,字符串,枚举,类,注释和数组,并且默认值不能为null:

代码语言:javascript
复制
@Author(name = "Roland",
 created = "2020/04/16",
 revision = 3,
 reviewers = {"WSO2", "Shankar"})
public class SimpleAnnotationsTest {…}

当注释只有一个元素且其名称为value时,可以省略:

代码语言:javascript
复制
@SuppressWarnings(value = "unchecked")
void myMethod() { ... }

要么

代码语言:javascript
复制
@SuppressWarnings("unchecked")
void myMethod() { ... }

如果注释中没有元素,则可以省略括号,如前面的@Override示例所示。

代码语言:javascript
复制
@Override
void myAnnotationUsageMethod() { ... }

也可以在同一声明上使用多个注释:

代码语言:javascript
复制
@Author(name = "Roland Hewage")
@EBook
class MyClass { ... }

如果注释具有相同的类型,则称为重复注释:

代码语言:javascript
复制
@Author(name = "Roland Hewage")
@Author(name = "Rosy Buhat")
class MyClass { ... }

从Java SE 8版本开始,支持重复注释

注释类型可以是Java SE API的java.lang或java.lang.annotation包中定义的类型之一。在前面的示例中,Override和SuppressWarnings是预定义的Java批注。也可以定义自己的注释类型。上一个示例中的Author和Ebook注释是自定义注释类型。

注释可以定义其某些或所有元素的默认值。具有默认值的元素可以从注释声明中省略。

例如,假设注释类型作者定义了修订的默认值(默认为1)和审阅者(默认为空的String数组),则以下两个注释声明是等效的:

代码语言:javascript
复制
@Author(name = "Roland",
        created = "2018/04/18",
        revision = 1,
        reviewers = {})
public class SimpleAnnotationsTest() {…}

等于

代码语言:javascript
复制
@Author(name = "Roland",        // defaults are revision 1
        created = "2019/04/16") // and no reviewers
public class SimpleAnnotationsTest() {…}

可以在哪里使用注释

注释可以应用于声明:类,字段,方法和其他程序元素的声明。当在声明上使用时,每个注释通常会按照惯例出现在自己的行上。

从Java SE 8发行版开始,注释也可以应用于类型的使用。这里有些例子:

类实例创建表达式:

代码语言:javascript
复制
new @Interned MyObject();

类型转换:

代码语言:javascript
复制
myString = (@NonNull String) str;

实现子句:

代码语言:javascript
复制
class UnmodifiableList<T> implements
        @Readonly List<@Readonly T> { ... }

引发异常声明:

代码语言:javascript
复制
void monitorTemperature() throws
        @Critical TemperatureException { ... }

这种形式的注释称为类型注释

声明注释类型

许多注释会替换代码中的注释。

假设开发人员传统上以提供重要信息的注释开始每个类的主体:

代码语言:javascript
复制
public class Generation3List extends Generation2List {

   // Author: Roland Hewaage
   // Date: 2019/04/16
   // Current revision: 6
   // Last modified: 2019/04/18
   // By: Roland Hewage
   // Reviewers: Alice, Bill, Cindy

   // class code goes here
}

要使用注释添加相同的元数据,必须首先定义注释类型。这样做的语法是:

代码语言:javascript
复制
@interface ClassPreamble {
   String author();
   String date();
   int currentRevision() default 1;
   String lastModified() default "N/A";
   String lastModifiedBy() default "N/A";
   // Note use of array
   String[] reviewers() default {};
}

批注类型定义看起来类似于接口定义,在该接口定义中,关键字interface前面带有at符号(@)(@ = AT,与批注类型一样)。注释类型是接口的一种形式

先前的注释定义的主体包含注释类型元素声明,它们看起来很像方法。请注意,它们可以定义可选的默认值。

定义注释类型后,您可以使用该类型的注释,并在其中填充值,如下所示:

代码语言:javascript
复制
@ClassPreamble (
   author = "Roxana Chatu",
   date = "2018/06/23",
   currentRevision = 6,
   lastModified = "2018/09/12",
   lastModifiedBy = "Roly Ross",
   // Note array notation
   reviewers = {"Alice", "Bob", "Cindy"}
)
public class Generation3List extends Generation2List {

// class code goes here

}

要使@ClassPreamble中的信息出现在Javadoc生成的文档中,必须使用@Documentedannotation注释@ClassPreamble定义:

代码语言:javascript
复制
// import this to use @Documented
import java.lang.annotation.*;

@Documented
@interface ClassPreamble {

   // Annotation element definitions
   
}

Java SE API中预定义了一组注释类型。Java编译器使用某些注释类型,而某些注释类型适用于其他注释。

Java语言使用的注释类型

在java.lang中定义的预定义注释类型为@ Deprecated,@ Override和@SuppressWarnings。

1. @已弃用

@Deprecated注释指示已标记的元素已弃用,不应再使用。每当程序使用带有@Deprecated批注的方法,类或字段时,编译器都会生成警告。不推荐使用元素时,还应使用Javadoc @deprecated标记对其进行记录,如以下示例所示。

在Javadoc注释和注释中使用at符号(@)并非偶然:它们在概念上相关。另外,请注意,Javadoc标记以小写字母d开头,注释以大写字母D开头。

代码语言:javascript
复制
// Javadoc comment follows
/**
 * @deprecated
 * explanation of why it was deprecated
 */
@Deprecated
static void deprecatedMethod() { }

2. @Override

@Override注释通知编译器该元素用于覆盖超类中声明的元素。

代码语言:javascript
复制
// mark method as a superclass method
// that has been overridden
@Override 
int overriddenMethod() { }

虽然在重写方法时不需要使用此批注,但它有助于防止错误。如果标有@Override的方法未能正确覆盖其父类之一中的方法,则编译器将生成错误。

3. @SuppressWarnings

@SuppressWarnings批注告诉编译器禁止以其他方式生成的特定警告。在下面的示例中,使用了不赞成使用的方法,并且编译器通常会生成警告。但是,在这种情况下,注释会导致警告被抑制。

代码语言:javascript
复制
// use a deprecated method and tell 
// compiler not to generate a warning
@SuppressWarnings("deprecation")
void useDeprecatedMethod() {
    // deprecation warning
    // - suppressed
    objectOne.deprecatedMethod();
}

每个编译器警告都属于一个类别。Java语言规范列出了两类:不推荐使用和未选中。与泛型出现之前编写的旧代码进行交互时,可能会发生未经检查的警告。要禁止显示多类警告,请使用以下语法:

代码语言:javascript
复制
@SuppressWarnings({"unchecked", "deprecation"})

4. @SafeVarargs

@SafeVarargs批注应用于方法或构造函数时,声明该代码不会对其varargs参数执行潜在的不安全操作。使用此注释类型时,将抑制与varargs使用有关的未经检查的警告。

5. @FunctionalInterface

Java SE 8中引入的@FunctionalInterface批注指示类型声明旨在作为功能接口,如Java语言规范所定义。

自引入注释以来,许多库和框架已将注释合并到其较新的发行版中。通过在源代码中使用注释,这些库和框架减少了甚至消除了对配置文件的需求。

辉煌的例子可见于:

  • Java Enterprise Edition及其主要组件-Enterprise JavaBeans,Java Persistence API或Web Services API
  • Spring框架-彻底用于核心框架和其他Spring项目中的配置,依赖项注入和控制反转
  • 接缝,焊缝,Guice
  • Apache Struts 2

适用于其他注释的注释

适用于其他注释的注释称为元注释。java.lang.annotation中定义了几种元注释类型。

1. @保留

@Retention注释指定标记的注释的存储方式:

  • RetentionPolicy.SOURCE –标记的注释仅保留在源级别中,并且被编译器忽略。
  • RetentionPolicy.CLASS –标记的注释由编译器在编译时保留,但被Java虚拟机(JVM)忽略。
  • RetentionPolicy.RUNTIME-标记的注释由JVM保留,因此可以由运行时环境使用。

2. @记录

@Documented注释表示,每当使用指定的注释时,都应使用Javadoc工具记录这些元素。(默认情况下,Javadoc中不包含注释。)

3. @Target

@Target批注标记了另一个批注,以限制该批注可以应用于哪种Java元素。目标注释将以下元素类型之一指定为其值:

  • ElementType.ANNOTATION_TYPE可以应用于注释类型。
  • ElementType.CONSTRUCTOR可以应用于构造函数。
  • ElementType.FIELD可以应用于字段或属性。
  • ElementType.LOCAL_VARIABLE可以应用于局部变量。
  • ElementType.METHOD可以应用于方法级注释。
  • ElementType.PACKAGE可以应用于包声明。
  • ElementType.PARAMETER可以应用于方法的参数。
  • ElementType.TYPE可以应用于类的任何元素。

4. @继承

@Inherited批注指示批注类型可以从超类继承。(默认情况下,这是不正确的。)当用户查询注释类型并且类没有该类型的注释时,将为该注释类型查询类的超类。该注释仅适用于类声明。

5. @可重复

Java SE 8中引入的@Repeatable注释表示可以将标记的注释多次应用于同一声明或类型使用.

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-17,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 软件测试test 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 注释基础
  • 可以在哪里使用注释
  • 声明注释类型
  • 适用于其他注释的注释
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com