Java注释中的/**和/*

218

什么是以下两个单词的区别:

/**
 * comment
 *
 *
 */

/*
 * 
 * comment
 *
 */

Java中的接口是什么?在什么情况下应该使用它们?

9个回答

257
第一种形式称为Javadoc。当您编写代码的正式API时,可以使用此工具生成。例如,Java 7 API页面使用了Javadoc并由该工具生成。
在Javadoc中常见的元素包括:
  • @param:用于指示将传递给方法的参数以及它们预期具有的值

  • @return:用于指示方法将返回什么结果

  • @throws:用于指示方法在某些输入情况下抛出异常或错误

  • @since:用于指示此类或函数最早可用的Java版本

例如,这是Integercompare方法的Javadoc:
/**
 * Compares two {@code int} values numerically.
 * The value returned is identical to what would be returned by:
 * <pre>
 *    Integer.valueOf(x).compareTo(Integer.valueOf(y))
 * </pre>
 *
 * @param  x the first {@code int} to compare
 * @param  y the second {@code int} to compare
 * @return the value {@code 0} if {@code x == y};
 *         a value less than {@code 0} if {@code x < y}; and
 *         a value greater than {@code 0} if {@code x > y}
 * @since 1.7
 */
public static int compare(int x, int y) {
    return (x < y) ? -1 : ((x == y) ? 0 : 1);
}

第二种形式是块注释(多行注释)。如果您想在注释中使用多行,则可以使用此形式。
我会说,您只需要节制地使用后一种形式;也就是说,您不希望用过多的块注释来描述方法/复杂函数应该具有的行为。
由于Javadoc是两者中更详细的,而且您可以生成实际文档作为使用它的结果,因此使用Javadoc比使用简单的块注释更可取。

37
使用Javadoc而不是简单的块注释的另一个好处是,当你在Java元素(例如方法签名、字段声明、类等)之前放置Javadoc注释时,这将使IDE(至少是Eclipse)在您移动光标或悬停鼠标在该Java元素的引用上时显示您的注释(例如在工具提示中)。 - SantiBailors
使用Java文档注释来注释变量是否可以? - the_prole
@the_prole:你可以这样做,但是除非它是常量包的一部分,否则我不认为它有太多价值。即使是在常规注释方面,根据我的经验,行内注释更有价值。 - Makoto

145
对于Java编程语言而言,/* ... */// ... 都是传统注释。请参阅Java语言规范。对于Java编程语言,/* ... *//** ... */都是传统注释的实例,并且它们在Java编译器中被完全相同地处理,即被忽略(或更正确地说:被视为空格)。
然而,作为Java程序员,您不仅使用Java编译器,还使用包括编译器、IDE、构建系统等在内的整个工具链。一些工具解释事物的方式与Java编译器不同。特别是,在Java 平台中包含生成文档的Javadoc工具会解释/** ... */之间的部分作为文档。
这类似于像FIXMETODO这样的标记:如果您包括注释如// TODO: fix this// FIXME: do that,大多数IDE将突出显示此类注释,以便您不会忘记它们。但对于Java而言,它们只是注释。

51
+1 对于强调 Javadoc 语法不是 Java 语言的一部分做出了重要区分,这是目前其他答案没有涵盖的。 - Chris Hayes
2
这就是为什么你可以在Maven中编译一个项目,但一旦你决定附加JavaDocs,它就开始抱怨,因为javadoc工具无法解释某些内容。 - Captain Man
@Hoopje 我也一直认为Java有三种注释类型(EOL、传统和Javadoc)...但后来我读了JLS,发现它和你说的一样。现在,我远远不理解Java编译器底层的所有东西,但是在检查了这个 code 之后,我觉得即使Java编译器也没有将传统和Javadoc注释视为同等待遇……对我来说,它明显区分了三种注释类型。 - Patrick B.
@Hoopje,即使是在JLS的第3.7段中也明确说明了:“//在以/*或/**开头的注释中没有特殊含义”,这对我来说隐含地承认了除行末注释之外还存在两种注释类型。所以,这里我错过了什么吗? - Patrick B.
@PatrickB. 不是这样的,那里识别的是注释的结尾。他们需要记住最后一个字符是否为星号(CommentTailStar),或者不是(CommentTail),以便在斜线跟随星号时关闭注释。这就是为什么如果下一个字符是NotStarNotSlash,他们会返回到CommentTail。 - Hoopje
显示剩余3条评论

20

第一种是Javadoc注释。可以通过javadoc工具处理,以生成您的类的API文档。第二种是普通的块注释。


15

阅读JLS文档的3.7节可以很好地解释Java中的注释。

有两种注释:

  • /* 文本 */

传统注释:从ASCII字符 /* 到ASCII字符 */ 中的所有文本都将被忽略(类似于C和C ++)。

  • //文本

行尾注释:从ASCII字符 // 到行尾的所有文本都将被忽略(类似于C ++)。


关于你的问题,

第一个。

/**
 *
 */

用于声明Javadoc技术

Javadoc是一种工具,它解析源文件中的声明和文档注释,并生成一组HTML页面描述类、接口、构造函数、方法和字段。您可以使用Javadoc doclet自定义Javadoc输出。Doclet是使用Doclet API编写的程序,指定由该工具生成的输出的内容和格式。您可以编写doclet来生成任何类型的文本文件输出,例如HTML、SGML、XML、RTF和MIF。Oracle提供了一个标准doclet来生成HTML格式的API文档。Doclet也可用于执行与生成API文档无关的特殊任务。

有关Doclet的更多信息,请参阅API

如在JLS中清楚地解释的那样,第二个将忽略/**/之间的所有文本,因此用于创建多行注释。


Java中的其他一些注释相关事项:

  • 注释不会嵌套。
  • //开头的注释中,/* 和 */没有特殊含义。
  • /* 或 /**开头的注释中,//没有特殊含义。
  • 词法语法表明,注释不会出现在字符字面量(§3.10.4)或字符串字面量(§3.10.5)内。

因此,以下文本是一个完整的注释:

/* this comment /* // /** ends here: */

“嵌套”这个动词在JLS的角度是否有与我们预期不同的特殊含义呢?对我来说,以下示例看起来像是嵌套注释,至少在视觉上是这样的(即使编译器词法分析算法没有将“内部”注释作为“注释”进行确认):/* 外部注释 // 内部注释 */// 外部注释 // 内部注释,以及 // 外部注释 /* 内部注释 */。但显然以下示例并没有显示出嵌套注释,因为源代码甚至无法编译:/* 外部注释 /* 内部注释 */ */ - Patrick B.

8

我认为现有的答案没有充分解决问题的这一部分:

何时应该使用它们?

如果您正在编写一个将在组织内发布或重复使用的API,则应为每个public类、方法和字段以及非final类的protected方法和字段编写全面的Javadoc注释。Javadoc应涵盖所有无法通过方法签名传达的内容,例如前提条件、后置条件、有效参数、运行时异常、内部调用等。

如果您正在编写内部API(由同一程序的不同部分使用的API),则可以说Javadoc的重要性较小。但是出于维护程序员的利益,仍应为任何方法或字段编写Javadoc,其中正确的用法或含义不是立即明显的。

Javadoc的“杀手级功能”是它与Eclipse和其他IDE紧密集成。开发人员只需将鼠标指针悬停在标识符上,就可以了解他们需要了解的所有内容。对于经验丰富的Java开发人员来说,不断地参考文档已成为第二天性,这提高了他们自己代码的质量。如果没有使用Javadoc记录您的API,经验丰富的开发人员将不想使用它。


5
以下 Java 代码清单中灰色字体为注释内容:
/** 
 * The HelloWorldApp class implements an application that
 * simply displays "Hello World!" to the standard output.
 */
class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello World!"); //Display the string.
    }
}

Java语言支持三种注释方式:
/* text */

编译器会忽略 /**/ 之间的所有内容。
/** documentation */

这表示一个文档注释(简称doc注释)。编译器会忽略这种类型的注释,就像它忽略使用/**/的注释一样。JDK javadoc工具在准备自动生成的文档时使用doc注释。

// text

编译器会忽略从//到行末的所有内容。
关于何时使用它们的问题:
当您想注释单行代码时,请使用//文本
当您想注释多行代码时,请使用/* 文本 */
当您想添加一些关于程序的信息,以供自动生成程序文档时,请使用/** 文档 */

3

第一个是用于Javadoc的,可以在类、接口、方法等顶部定义。您可以使用Javadoc来记录代码的作用,例如类的作用或方法的作用等,并生成报告。

第二个是代码块注释。例如,如果您有一些代码块不希望编译器解释,则可以使用代码块注释。

另外还有//,您可以在语句级别上使用它来指定后续行的代码应该做什么。

还有一些其他的,例如//TODO,这将标记您想要稍后完成的任务

//FIXME,当您有一些临时解决方案但您希望稍后再访问并改进时可以使用它。

希望这可以帮助您。


3
  • 单行注释,例如://注释
  • 多行注释,例如:/* 注释 */
  • javadoc注释,例如:/** 注释 */

4
这并没有比现有答案提供更多内容。 - shmosel
1
@shmosel 不是,但它可以概括它们。 - Det

-1

Java支持两种类型的注释:

  • /* 多行注释 */:编译器会忽略从/**/之间的所有内容。注释可以跨越多行。

  • // 单行注释:编译器会忽略从//到行末的所有内容。

一些工具,如javadoc,使用特殊的多行注释来实现其目的。例如,/** 文档注释 */是javadoc用于准备自动生成文档时使用的文档注释,但对于Java来说,它只是一个简单的多行注释。


12
Java语言仅支持两种注释方式。形如 /** .. */ 的注释是常规的多行注释,其中第一个字符恰好是一个星号。请注意,这只是一种注释方式,不代表实际代码中必须使用它。 - Chris Hayes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接