对于简单的构造函数和setter,Java中的参数是否有标准的可接受约定?
(I've seen the answer for C++,但两个社区的做法往往不同)
假设我有一个带有foo字段的C类。
我经常看到以下三个选项:
public C(Type foo_)
{
foo = foo_;
}
public void setFoo(Type foo_)
{
foo = foo_;
}
public C(Type foo)
{
this.foo = foo;
}
public void setFoo(Type foo)
{
this.foo = foo;
}
public C(Type bar)
{
this.foo = bar;
}
public void setFoo(Type bar)
{
this.foo = bar;
}
我倾向于使用2,但我想知道什么是正确的做法。
方案二是最常见的。在Java中,使用无意义的名称前缀或后缀来区分实例变量和局部变量的参数被认为是不好的做法。但名称本身没有惯例。使用任何名称使代码最容易理解。
方案二。
如果你看到“setFoo(String foo)”定义(例如在javadoc或hover中),你可以合理地期望字段“foo”被设置为参数“foo”的值。其他名称可能需要您仔细检查 - 例如将setName(String person)设置为person或者是否会采取其他操作(在人员表中查找名称等)?
不这样做的通常原因是你可能会不小心写
...... foo = foo;
代替
this.foo = foo;
这是一个没有做任何事情的参数的自我赋值。现代编译器捕获这一点 - 现代IDE在为字段创建setter时生成“this.foo = foo”语句。
在Eclipse中,您可以为字段创建getter和setter,当光标位于相关字段时,使用Ctrl-1。
我使用的约定是用m_作为成员变量的序言;如:
字符串m_foo;
这样,很明显哪些变量是成员,哪些不是。
另外,我的上一家公司在方法中用“the”开头的所有参数,如:
Public Strike(来自String,String Thorndum){
....
}
它使得很容易不将参数与内部变量混淆。
约定应该是使代码更容易阅读,并减少错误。
选项2在Java中最常见,但挑剔的Checkstyle不允许您使用此选项,因为本地var的名称会影响另一个。
因此,大多数使用以下内容:
foo(int thatBar) {
this.bar = thatBar;
}
使用此选项的唯一问题是其他人可能猜测您在类中使用了var命名条,因为如果不是,则不会为参数命名。
一个邪恶的人只能通过查看方法来使用这些信息来更好地理解你的课程。但为此你会使用一个重命名所有变量等的混淆器。
虽然从setter返回void
很常见,但有时返回实例的引用很方便:
public class Foo {
String value1, value2;
public Foo setValue1(String value1) {
this.value1 = value1;
return this;
}
public Foo setValue2(String value2) {
this.value2 = value2;
return this;
}
}
这允许您链接值的设置:new Foo().setValue1("A").setValue2("B");
我也看到选项2是最常见的选项:
int importance;
public int getImportance()
{
return importance;
}
public void setFoo(int importance)
{
this.importance = importance;
}
Eclipse和Netbeans等IDE将自动以上述格式编写getter和setter。
使用此方法有一些优点:
不在字段名称中使用下划线(_
)字符 - 不建议将非下划线用于非常量字段名称。
除了常量的标识符之外,不建议在标识符中使用下划线字符。
The Java Tutorials的Variables页面提到了关于下划线的以下内容:
如果您的变量存储一个常量值,例如
static final int
NUM_GEARS = 6
,则约定会略有变化,将每个字母大写并用后突字符分隔后续单词。按照惯例,下划线字符从未在别处使用过。
(重点补充。)
由于字段名称不是常量,根据该页面上的内容,不应在非常量字段中使用下划线。
IDE可以根据方法参数的名称自动添加Javadoc注释,因此在参数列表中使用该字段的名称将是有益的。
以下是自动生成的Javadoc的示例:
/**
*
* @param importance <-- Parameter name in Javadoc matches
* the parameter name in the code.
*/
public void setImportance(int importance)
{
this.importance = importance;
}
让Javadoc反映字段的名称还有另一个好处 - 具有代码完成功能的IDE可以使用Javadoc中的字段名称来自动填写参数名称:
// Code completion gives the following:
this.getImportance(importance);
赋予字段名称和参数名称含义将使您更容易理解参数实际表示的内容。
这些是我目前可以提出的一些优点,我相信它很可能是在Java中命名参数的最常用方法。
(1)非常C / C ++。 Java并不倾向于使用前导下划线。
我个人使用(2)几乎完全。
(3)只是让你的生活变得困难,因为很难想到成员和参数的两个有意义但简洁的名字。
我见过2和3使用最多。也就是说,答案取决于您所贡献的代码库所接受的标准。我认为在整个项目中保持一致比为每个Java开发人员提供一个“正确”的答案更重要。
Eclipse代码生成使用列表中的样式#2。
我知道当netbeans自动创建getter和setter时,它使用数字2方法。我个人通常会给变量添加温度,即foo = tempfoo
。但正如neesh所说,无论选择哪种方法,都应尽量保持一致
我个人使用foo(Bar parBar)
虽然我知道它通常被认为是不良的做法预先或后缀变量名称。
背后的原因很简单:清晰度
现在,如果你调用一个方法foo(Bar bar)
,它可能并不总是直观的bar
实际上是什么意思。即使它是,它仍然是一个痛苦的屁股。
this.bar = bar
甚至bar = bar
如何比bar = parBar
更清洁,更直观?我宁愿有一个前缀而不是逻辑歧义。
是选项2是最广泛使用的;虽然它有一个严重的问题:如果你的参数声明中有一个拼写错误 - 由于阴影可能会被忽视,例如:
class Whatever {
String val;
Whatever(String va1) { this.val = val; }
void printMe() { System.out.println(val.toString()); }
public static void main(String[] args) {
new Whatever("Hello").printMe();
}
}
这段代码编译得很好;你需要一秒钟才能理解那里的错误。如果你有疑问;把它打印出来;把它交给你的同事,问他们如果这个类被编译和执行会发生什么。我猜:75%+不会意识到会抛出NullPointerException。如果你转向val和va1的“看起来相同”的字体;那时没有人会注意到......
是的,现在您可能会看到有关此问题的警告,或者某些代码检查工具会告诉您发生了这种情况;当然,您的单元测试应该立即找到它。
但是:如果你避免这种模式,并使用前缀或“thatString”,你将永远不会遇到这个问题。因此,我真的不明白为什么它如此常用。
所以,我们坐在我们的团队中,在整理我们的编码风格指南时,我们说:永远不要使用选项2。
选项2是大多数Java风格指南推荐的。
我发现谷歌的Java风格指南非常有用:
更新链接(Jun-2019):https://google.github.io/styleguide/javaguide.html
或在网上搜索“Google Java Style Guide”
当您编写代码以使界面尽可能清晰时,我总是更喜欢在内部使用字段_name
,将其作为name
作为方法参数,将其优雅地指定为_name = name
。我在Fowler的Refactoring和其他类似的教科书中看到了这一点,虽然我看到了丑陋的机制,比如在内部使用name
这个字段然后使用aName
作为方法参数,呃。