我正在用Java编写一些不可变类型,并想知道如何命名访问器方法。 Java Bean规范说访问者的名称应该是getX或isX,但由于字段是final,所以没有setter,字段更像是属性而不是属性。
因为我更喜欢命名getter方法,如:
public T x()
而不是
public T getX()
请注意作为一个例子:
public int java.lang.String#length()
(这可能是在Java历史的早期指定的,所以那些惯例还没有。)
不可变对象暴露意味着通过我试图命名为动词而不是MyObject MyObject#setX()
的方法来创建自己的修改版本,这应该限制用户调用setX()的风险并认为对象已经改变了。所以:MyObject MyObject#shine(newShineLevel)
。
但这并不总是那么容易。您如何命名一种方法来调整Rectangle.setUpperLeft()
以外的矩形中的端点? Rectangle.adjustUpperLeft
也许,但现在我们正在远离惯例。
我想这个问题与所有语言都有关系,但这个问题尤其涉及Java。
答案 0 :(得分:7)
如果这些类可以与任何基于反射的框架一起使用,那么最好不要使用getX约定。例如,通过表达式“x.y”访问JSP和其他模板系统中的属性需要该对象具有方法getY()。
答案 1 :(得分:6)
即使对于不可变类型,约定getX()
仍然存在。一些例子:
java.lang.Integer.getInteger()
java.lang.Boolean.getBoolean()
确实有很多例如java.lang.String.length()
,但常见的惯例是使用 getX 。正如下面的答案中所提到的,分离原子 get 操作和对数据进行一些计算的方法至关重要。
另外值得一提的是,许多框架中的普通java bean依赖于getter / setter方便地命名为 getX 和 setX 这一事实。
答案 2 :(得分:6)
Java中用于访问类属性的约定(包括不可变类)是使用get
和set
前缀,因此我建议使用public final T getX()
。
String上的length()
方法未被调用getLength()
的原因是因为String类上没有名为length
的属性。
答案 3 :(得分:4)
当我这样说时,人们倾向于向我投票,但get
前缀实际上只是在写一个bean时才是强制性的。有许多示例表明使用get
。不仅String.length()
。您可以在原始包装类(intValue()
,doubleValue()
,booleanValue()
,...),枚举(name()
和ordinal()
)和集合({ {1}})和注释的设计方式似乎也鼓励了size()
- 更少的风格。 (Josh Bloch介绍了Effective Java中的主题,并提倡更具可读性get
- 更少样式,除非您实际编写bean。)
所以:使用get
前缀,您的对象可以用作bean。放弃它,你的代码更容易阅读。由你来决定你认为什么更重要。
我自己,我经常使用前缀,即使我不喜欢它,只是因为Eclipse为我自动生成它:)
答案 4 :(得分:0)
我坚持使用“获取”约定只是因为有很多其他工具可以使用它。例如,Jakara Commons BeanUtils。如果您具有正确的命名,则许多工具/库将默认工作,但如果您偏离了bean访问器约定,则需要配置。
我并不反对你推理偏离的说法,我认为从长远来看,你可能会更好地坚持使用get / set约定。
答案 5 :(得分:0)
使用get是一个好主意 - 从不强制使用,但人们会自动知道它是什么。
Get并不意味着你将它作为一个成员变量,实际上它应该隐藏这个事实。它可以轻松地访问计算值。
size(),length()等是在Borland发现他们需要get / set概念来实现他们的GUI构建器之前创建的(我不确定是谁提出了这个想法,但这就是原因)。
intValue,doubleValue等不是getter,它们是转换器,因此命名不同。
现在,所有这一切,如果您真的想使用x或getX,那么这是您的选择。大多数体面的工具集不再需要getter和setter,他们会使用注释 - 只需准备好让几个人多花几秒钟输入“get”然后输入“ctrl-space”而不是找到他们之后的内容