【问题标题】:Simple Getter/Setter comments简单的 Getter/Setter 注释
【发布时间】:2010-11-04 23:09:00
【问题描述】:

您使用什么约定来评论 getter 和 setter?这是我很长时间以来一直想知道的事情,例如:

/**
 * (1a) what do you put here?
 * @param salary (1b) what do you put here?
 */
public void setSalary(float salary);

/*
 * (2a) what do you put here?
 * @return (2b)
 */
public float getSalary();

我总是发现我在为 1a/b 和 2a/b 写几乎完全相同的东西,比如 1a) 设置员工的薪水,1b) 员工的薪水。这似乎是多余的。现在我可以看到,对于更复杂的内容,您可能会在 (a) 部分中写更多内容,以提供上下文,但对于大多数 getter/setter 而言,措辞几乎完全相同。

我只是好奇,对于简单的 getter/setter 是否可以只填写 (a) 部分或 (b) 部分。

你怎么看?

【问题讨论】:

标签: java comments javadoc setter getter


【解决方案1】:

绝对没有意义——最好不要让这种垃圾把你的代码弄得乱七八糟:

/**
 * Sets the foo.
 * 
 * @param foo the foo to set
 */
public void setFoo(float foo);

非常有用,如果需要的话:

/**
 * Foo is the adjustment factor used in the Bar-calculation. It has a default
 * value depending on the Baz type, but can be adjusted on a per-case base.
 * 
 * @param foo must be greater than 0 and not greater than MAX_FOO.
 */
public void setFoo(float foo);

尤其是对属性实际含义的解释在领域模型中可能至关重要。每当我看到一个 bean 的属性名称晦涩难懂,只有投资银行家、生物化学家或量子物理学家才能理解,并且 cmets 解释说 setGobbledygook() 方法“设置了 gobbledygook”。我想掐死某人。

【讨论】:

  • 我的观点完全正确,最糟糕的是特定领域的模型,只有领域专家知道该属性的含义。
  • 即使它有用,你会为 getFoo() 做什么。你会为 getFoo() 复制相同的注释吗?
  • @cmv:显然“参数”部分不会被复制。我不确定将信息附加到两个访问器的价值是否直接证明复制信息的合理性。可能是。更好的方法是将一个评论附加到两者上;我相信这在 Project Lombok 中可用。
  • @VinothKumar:也许最好简单解释一下 getter 中的属性(如“Foo 是 Bar-calculation 中使用的调整因子。”)以及在设置器(或者是否有必要初始化该值 - 在答案的示例中,不需要初始化 Foo 因为“它具有取决于 Baz 类型的默认值”)。
  • +1 表示“只有投资银行家、生物化学家或量子物理学家才能理解的晦涩名称”
【解决方案2】:

我通常只为 setter 填充 param 部分,为 getter 填充 @return 部分:

/**
 * 
 * @param salary salary to set (in cents)
 */
public void setSalary(float salary);

/**
 * @return current salary (in cents, may be imaginary for weird employees)
 */
public float getSalary();

这样,javadoc 检查工具(例如 Eclipse 的警告)就会干净利落,不会出现重复。

【讨论】:

  • 你能改正错字吗? "@return 用于设置器的部分"
  • salary() 的评论中还有一个错字。这不是 JavaDoc 注释。
  • 我同意这是评论访问者的最佳方法。
  • 为了消除我们工具中过于迂腐的警告而在代码中添加噪音对我来说是错误的。如果它没有为程序员增加价值,那么正确的解决方案是拒绝/修复工具的冗长性和/或减轻我们对跳槽的关心程度,以便工具奖励我们。分析工具应该帮助我们并节省精力,而不是为我们创造更多毫无意义的任务。
  • @Lyle 这可能是真的,但我觉得程序员几乎总能说出一些有用的东西来描述 getter/setter,而不仅仅是方法签名。是的,有些情况下程序员很懒,只是在注释中重复方法签名,但我认为一般来说,强制是一种有用的行为。
【解决方案3】:

一般没什么,如果我能帮忙的话。 getter 和 setter 应该是不言自明的。

我知道这听起来像是一个无法回答的问题,但我会尽量利用我的时间来评论需要解释的事情。

【讨论】:

  • 沿着这些思路的另一个有效答案可能是“带有 getter 和 setter 的设计没有正确理解封装的概念”:)
  • @Trejkaz:不正确,因为访问器方法允许只读或只写属性,以及多态性(以及包装、代理等)。
  • 它们可能允许这些事情,但通常构建器模式可以替换 setter(不那么可变)或访问者模式可以替换 getter(更灵活)。
  • 我当然喜欢并使用构建器模式,但是对 POJO 的支持非常多(例如在 Hibernate 中),无论好坏,getter 和 setter 仍然占据着非常重要的位置。恕我直言,这是 Java 最糟糕的事情,在编写了十多年重复的 JavaDocs 之后,我准备订阅@sleske 的建议。
【解决方案4】:

我想说,如果 getter 和 setter 有某种副作用,或者需要初始化之外的某种先决条件(即:getter 将从数据结构中删除一个项目,或者为了设置你需要先有 x 和 y 的东西)。否则这里的 cmets 就相当多余了。

编辑:此外,如果您确实发现 getter/setter 涉及很多副作用,您可能希望更改 getter/setter 以具有不同的方法名称(即:堆栈的 push 和 pop) [感谢下面的cmets]

【讨论】:

  • 可以说,您应该将具有副作用的 getter 的名称更改为更清楚,因为并非所有开发人员都会阅读 cmets。
  • 这很好 - 但这需要您 API 的用户知道,如果有任何副作用,他们会被记录在案
  • akf,我在发帖后就是这么想的 :) 我想我会把它添加到我的回复中。
  • 但是如果您不记录“愚蠢”的 getter 和 setter(这也是我更喜欢的!) - 您如何摆脱缺少 javadoc 的 Eclipse 警告?我不想让我的工作区被这样的警告弄得乱七八糟,但我也不希望对所有其他方法都禁用该警告...
【解决方案5】:

问问自己,当 cmets 被视为 JavaDocs(从浏览器)时,您希望人们看到什么。许多人说文档是不必要的,因为它很明显。如果字段是私有的,这将不成立(除非您为私有字段显式打开 JavaDocs)。

在你的情况下:

public void setSalary(float s)
public float getSalary()

不清楚工资是用什么表示的。是美分、美元、英镑、人民币?

在记录 setter/getter 时,我喜欢将内容与编码分开。示例:

/**
 * Returns the height.
 * @return height in meters
 */
public double getHeight()

第一行说它返回高度。返回参数记录高度以米为单位。

【讨论】:

  • 虽然我同意你的观点,但我认为必须确保函数 cmets 不会为一个错误选择的、非显式的函数名称而做出选择。
  • 我是 JavaDocs 的忠实支持者,也是自文档代码的忠实支持者。所以至少对于二传手,我会做类似public void setSalary(float aud)(或更现实地说,public void setSalary(BigDecimal aud))的事情。更好的是,该属性应该是abstract class CurrencyAmount 类型,而后者又具有属性java.util.Currency currencyjava.math.BigDecimal amount。我合作过的大多数开发人员都非常懒惰使用 JavaDoc,但是像这样强制执行 API 可以减少这方面的问题。
  • 如果单位是 SI 单位,例如米/秒,则不需要记录,如果不是 Si 单位,则必须记录或更好地命名以包含非标准单位,例如身高英尺
【解决方案6】:

他们为什么不只包含一个引用标签来让您评论字段值以及来自 getter 和 setter 的引用。

/**
* The adjustment factor for the bar calculation.
* @HasGetter
* @HasSetter
*/
private String foo;

public String getFoo() {
  return foo;
}

public void setFoo() {
  this foo = foo;
}

以便文档适用于 getter 和 setter 以及字段(如果打开了私有 javadocs)。

【讨论】:

  • 我同意。然后我意识到,为什么要写所有这些样板文件呢?请参阅我对 Project Lombok 的回答。
【解决方案7】:

使用Project Lombok 可以避免这种样板。只需记录字段变量,即使它是 private,并让 Lombok 注释生成正确记录的 getter 和 setter。

对我来说,仅此一项好处就值得costs

【讨论】:

    【解决方案8】:

    我对基本上说全面记录是浪费时间的答案感到非常失望。除非您在文档中明确说明,否则您的 API 的客户应该如何知道名为 setX 的方法是标准 JavaBean 属性设置器

    如果没有文档,调用者将不知道该方法是否有任何副作用,除了对所遵循的明显约定交叉手指。

    我敢肯定,我不是唯一一个不幸地发现一个名为 setX 的方法所做的不仅仅是设置一个属性的方法。

    【讨论】:

    • 如果没有文档,任何调用者都会假设一个名为 setX 的方法设置了 X。因此,如果 setX 确实设置了 X,而没有做任何其他重要的事情,那么您就不需要文档。
    • 太好了!现在这家 CrudTech 公司(我正在编写其 API)是否遵循您的约定,或者它是否遵循此线程上的其他人的约定?嗯
    • 如果方法只是设置 price 属性的值,那么在 setPrice 文档中编写“设置价格”是没有意义的,但如果它也是例如更新 totalPrice 属性并重新计算税收,这种行为显然应该记录在案。
    • 您似乎要求文档说明“这符合您的预期。”这有点像在一杯咖啡上写“小心:热”。在一个完美的世界里,没有必要说这样的话。
    • 是的 - 使用了 API,其中调用诸如 setX 之类的方法具有超出预期的副作用,我确实可以自信地说这不是一个完美的世界。
    【解决方案9】:

    如果getter/setter中没有特殊操作,我通常会写:

    使用 Javadoc(带有私有选项):

    /** Set {@see #salary}. @param {@link #salary}. */
    public void setSalary(float salary);
    

    和/或

    /** 
     * Get {@see #salary}.
     * @return {@link #salary}.
     */
    public float salary();
    

    使用 Doxygen(带有私人提取选项):

    /** @param[in] #salary. */
    public void setSalary(float salary);
    
    /** @return #salary. */
    public float salary();
    

    【讨论】:

    • 这种方法的问题是Javadoc默认不生成私有文档!在这种情况下,参考标记 {@see #salary} 在生成的文档中无效。
    【解决方案10】:

    评论访问器,特别是如果他们不在任何地方做任何操作,是不必要的并且浪费指尖。

    如果阅读您的代码的人无法理解 person.getFirstName() 返回一个人的名字,您应该尽一切努力让他被解雇。如果它做了一些数据库魔法,掷了几个骰子,调用名字的秘书来获取名字,可以安全地假设这是一个不平凡的操作,并做好记录。

    另一方面,如果您的 person.getFirstName() 没有返回一个人的名字......好吧,我们不要去那里,好吗?

    【讨论】:

    • 如果 getFirstName() 返回 null 怎么办?这将记录在哪里?
    • security.getFinalMaturity() 怎么样?并非所有属性名称都具有立即可以理解的含义。你会因为不知道这意味着什么而被解雇吗?
    • 如果方法是通过swizzling实现的呢?除非有明确的记录,否则你怎么知道?除非文档说是标准制定者,否则您怎么知道它是标准制定者?
    • get/set 在我看来应该保留给 getter 和 setter。数据库查找应命名为“lookupPerson”左右。
    【解决方案11】:

    如果字段名称足以描述内容,则不要输入任何内容。

    一般来说,让代码独立存在,并尽可能避免注释。这可能需要重构。

    编辑:以上仅指 getter 和 setter。我相信任何不平凡的事情都应该被正确地 javadoc'ed。

    【讨论】:

    • 评论和记录是有区别的。
    • 非常正确。这就是为什么我不评论 getter 和 setter 的原因。它们应该是自我解释的,并且添加注释表明代码不是自我解释的。
    【解决方案12】:

    可以填写 (b) 部分,特别是如果您在字段声明中添加注释,说明该字段的全部内容。

    【讨论】:

    • 不好 - 人们不阅读字段 cmets。默认情况下,Javadoc 甚至不会生成私有文档,当您在方法调用上使用快速帮助时,IDE 不会向您显示字段文档。
    • 除非需要,否则人们不会阅读字段 cmets。一旦有需要,信息越多越好。
    【解决方案13】:

    如果 javadoc 没有添加任何内容,我会删除 javadoc 并使用自动生成的 cmets。

    【讨论】:

      【解决方案14】:

      我总是填写两个。打字所花费的额外时间可以忽略不计,一般来说,更多信息总比更少信息要好。

      【讨论】:

      • 如果你说“这是一个属性设置器”,它们只是不言自明的。否则 API 的客户端根本不知道方法内部实际发生了什么
      • 谁说的不言自明?
      猜你喜欢
      • 2013-08-09
      • 2011-11-09
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      相关资源
      最近更新 更多