在接口中添加Javadoc注释并在实现中添加非Javadoc注释是正确的做法吗?
当您自动生成注释时,大多数IDE会为实现生成非JavaDoc注释。难道具体方法不应该有描述吗?
对于仅限于实现的方法(非覆盖方法),可以使用文本复制,特别是当它们是公共方法时。
如果你有一个需要覆盖方法的情况,并且你要复制任何文本,则绝对不要这样做。文本复制是导致差异的一种可靠方式。因此,用户会根据他们检查的方法是在超类型还是子类型中来理解您的方法,从而产生不同的理解。使用@inheritDoc
或不提供文档-IDE将采用其Javadoc视图中可用的最低文本。
顺带说一下,如果您的覆盖版本添加了超类型文档的内容,那么您可能会遇到麻烦。我在博士期间研究了这个问题,并发现通常情况下,如果通过超类型调用方法,人们将永远不会意识到覆盖版本中的额外信息。
解决这个问题是我构建的原型工具的主要功能之一-每当您调用方法时,都会提示您的目标或任何潜在覆盖目标是否包含重要信息(例如,冲突行为)。例如,在地图上调用put时,会提醒您,如果您的实现是TreeMap,则您的元素需要是可比较的。
实现和接口都应该有Javadoc文档。使用一些工具,你可以通过@inheritDoc关键字继承接口的文档。
/**
* @inheritDoc
*
* This implementation is very slow when b equals 3.
*/
public foo(int b)
{ ... }
{@inheritDoc}
,但只有在您首先没有注释@Override
的情况下才起作用。 - ksnortum比较好的做法是将
/**
* {@inheritDoc}
*/
根据实现的Javadoc(除非有关于实现细节需要额外解释的内容)。
通常情况下,当你重写一个方法时,你需要遵循基类/接口中定义的契约,因此你不想在任何情况下改变原始的javadoc。因此,在其他答案中提到的使用@inheritDoc
或@see
标记是不必要的,实际上只会在代码中产生噪音。所有合理的工具都会根据这里指定的规定从超类或接口继承方法javadoc:
Inherit from classes and interfaces - Inheriting of comments occurs in all
three possible cases of inheritance from classes and interfaces:
- When a method in a class overrides a method in a superclass
- When a method in an interface overrides a method in a superinterface
- When a method in a class implements a method in an interface
一些工具(我指的是Eclipse!)在覆盖方法时默认生成这些内容,这实际上是一种糟糕的情况,但它并不证明将您的代码弄得很杂乱是有用的。
当然也会出现相反的情况,即您实际上想要向覆盖方法添加注释(通常是一些额外的实现细节或使契约更严格)。但在这种情况下,您几乎从不想像这样做:
/**
* {@inheritDoc}
*
* This implementation is very, very slow when b equals 3.
*/
为什么?因为继承的注释可能非常长。这种情况下,谁会注意到3个长段落后面的额外句子呢?相反,只需写下自己的评论即可。所有javadoc工具都会显示某种由...指定链接,您可以单击该链接以阅读基类注释。混合它们是没有意义的。
@see
生成一个指向接口描述的链接。但我认为添加一些有关实现细节的详细信息也是很好的。
@see
链接接口方法是一种好的实践,足以满足需求。如果从接口方法中复制javadoc到具体实现中,则只是重复信息,并且很快可能不一致。但是,任何关于实现的额外信息都应添加到javadoc中。 - PiotrSjoerd正确地指出,接口和实现都应该有JavaDoc。接口JavaDoc应该定义方法的契约-方法应该做什么,它需要哪些输入,它应该返回哪些值以及在错误情况下它应该做什么。
实现文档应注意对契约的扩展或限制,还应提供适当的实现细节,特别是性能。
出于生成Javadoc的考虑,这确实很重要。如果您仅使用接口声明对具体实现的引用,则不需要考虑,因为IDE将检索接口的方法。