Java中用于获取和设置属性的命名约定

39
如果我有以下私有成员变量:
private int xIndex;

我该如何为我的getter/setter命名:

getXindex()
setXindex(int value)

或者
getxIndex()
setxIndex(int value)

编辑:或者

getXIndex()
setXIndex(int value);

?


8
将你的字段命名为"indexX"或其他名称,问题就解决了……不要过度复杂化——即使setxIndex是Bean的正确方式,将方法命名为setxIndex会增加代码的WTF因素而没有给你带来任何回报。如果你的司机生病了,请不要想着如何修理汽车,应该替换司机。 - user719662
8个回答

42

正确答案是

getxIndex()
setxIndex(int value)

如果你希望将它们作为属性使用,遵循JavaBeans API specification8.8节:推断名称的大写规范(例如,在JSP中通过${object.xIndex}访问它们)。


8
我写了一篇关于Java Bean的getter/setter方法的博客文章:http://dertompson.com/2013/04/29/java-bean-getterssetters/。 - Thomas Einwaller
2
我认为这不正确。第8.8节涉及从方法名推断属性名的大写形式。而这个问题是关于根据属性名命名方法的反向过程。Inspector.decapitalize()的javadoc说明它是一个“将字符串转换为普通Java变量名称的方法”,而不是像这种情况下的方法名称。 - Mirza Dobric
1
@SotiriosDelimanolis,你引用规范中的那句话是关于大写字母的。因此,在这里不适用。 - Marcel Stör
1
如果您将getter getXIndex进行小写处理,那么decapitalize方法会查看XIndex并决定没有需要小写处理的内容 - 因此它返回XIndex,而该属性不存在。请换个角度思考。 - Thomas Einwaller
1
实际上这是错误的答案.. 正确的答案是getXIndex(); "方法名必须以set/get/is为前缀,后跟大写的属性首字母,再后跟属性名称的其余部分。" JAVA SE 8 OCA - Mahmoud Turki
显示剩余3条评论

10
根据1997年的JavaBeans API规范,应该如Thomas Einwaller所描述的那样:
// According to JavaBeans API specification
public int getxIndex() { return xIndex; }
public void setxIndex(int xIndex) { this.xIndex = xIndex; }

很不幸,getxsetx都不是单词。在极少数情况下,如果这会形成一个单词或首字母缩略语,它会产生误导性,例如方法setiMessage很可能与SETI无关。 使用代码质量的唯一有效衡量标准(每分钟WTFs),我评估这是糟糕的代码。

如果我们修改为遵循命名方法的惯例,那么它将是:

// According to Java naming convention
public int getXIndex() { return xIndex; }
public void setXIndex(int xIndex) { this.xIndex = xIndex; }

JavaBeans规范为什么违反惯例?这要归结于JavaBeans规范的以下一句话:
“然而,为了支持偶尔使用全大写名称,我们检查名称的前两个字符是否都是大写字母,如果是,则保持不变。”
我不清楚这是指何种类型的全大写名称用法。根据惯例,字段名称应采用驼峰式命名法。似乎我们生成非常规的方法名称是为了支持由20多年前的文档决定的非常规字段名称。
还应该注意的是,即使在工具中JavaBeans规范似乎得到了极大的支持,但并不是专门使用的。例如,Kotlin将不会将xIndex识别为上述示例中的属性。相反,Kotlin属性var xIndex = 0将导致Java方法getXIndexsetXIndex。这似乎是JetBrains支持的一个错误,但我无法看到他们如何在不进行破坏性更改的情况下解决这个问题。
一些支持JavaBeans规范的工具并不总是支持它,例如 JacksonSwagger Code Generator 就已经被修补以符合它。即使 IntelliJ 根据 JavaBeans 规范生成访问器,文档中的 example 却与之不同。这可能是因为人们不知道该标准,自然更喜欢常规的方法命名约定。
那么何时应遵循 JavaBeans 规范呢?当属性名称应由依赖此标准的工具通过访问器推断时,我们可能需要使用它。例如,除非使用注释,否则 Jackson 将依赖于通过 getxIndexsetxIndex 方法访问属性 xIndex
什么情况下应避免使用此标准?按照我的建议:当代码应由人阅读和理解时。因为在命名方法时不使用正确的驼峰式大小写会误导信息。
如果按照我的方式,我们将使用常规命名约定,即 getXIndexsetXIndex。但是,鉴于现实情况,我认为最好的解决方案是 @vaxquis 提出的建议:
将你的字段命名为"indexX"或其他名称,问题就解决了...不要过度复杂化事情 - 即使setxIndex是Beans的正确方式,但命名方法为setxIndex会增加代码的WTF因素,而不会给你带来任何回报。关于JavaBeans规范的任何评论都应按照规范本身的规定发送到java-beans@java.sun.com。{{}}

如果setIndexX不可行,我会使用setXIndex并添加一个BeanInfo类来处理规范中这个不直观的特殊情况。 - toolforger

4

应该是:

getXIndex()
setXIndex(final int xIndex)

2
如果这是正确答案,为什么IDE(测试Intellij,也已阅读Eclipse)生成其他内容?它们会生成getxIndex()和setxIndex()。有人可以澄清吗? - kctang
9
不正确,这些Getter方法不符合Java Bean命名规范。 - Thomas Einwaller
5
这个答案不正确,@ThomasEinwaller的答案是正确的,因为这已经明确规定了,我们无需争论 :) - Martin C.
1
@kctang!因为正确的命名属性的方式是Thomas所写的。我将属性命名为cDate,并且我得到了PropertyNotFoundException:**在类型上无法读取属性[cDate]**。 - undefined

1

方法名称应该是动词,采用混合大小写,首字母小写,内部单词的首字母大写。


0

你应该使用java.beans包中的Introspector.decapitalize,因为它符合Java规则,所以不会有任何问题。


0

Eclipse IDE 会自动生成以下形式的 setter 和 getter:

getxIndex()
setxIndex(int value)

这符合Java Beans API规范。


0
我只是想指出我遇到的问题。我给属性命名为,然后我得到了异常:类型上的属性[cDate]不可读。所以正确的答案是:
public int getxIndex(){...}
public MyClass setxIndex(final int xIndex){...}

Thomas解释得更详细。


-2

我认为getXindex()是最好的方式。getter应该以'get'开头,后面跟着成员名称,其首字母大写。另外,我听说的最新惯例是,我们应该避免连续的多个大写字母。例如,getHTMLtooltip是错误的。它应该改为getHtmlTooltip。此外,您应该尝试使所有成员都是final,并且不应该需要setter,因为类将是不可变的;)


@m_pGladiator: 关于不可变性:虽然这显然是理想的,但并非所有类都可以被设置为不可变。但当然:如果不需要,则应仅存在setter。 @Simon: 主要原因是线程安全。如果一个类是不可变的,就不会出现通过单独的线程进行并发修改的问题。 - Sean Patrick Floyd
抱歉,我没有读取“javabeans”标签。Beans架构假定有getter和setter,并不支持不可变性。 - m_pGladiator
踩一下,因为问题中提到的情况已在规范中指定,请查看其他答案。 - Martin C.

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