Java构造函数和简单设置器中参数命名的最佳实践
Java中的参数是否有一个标准的可接受的约定,以简化构造函数和设置器?
( 我已经看到了C ++的答案 ,但是两个社区的做法往往不同)
假设我有一个带有foo字段的类C,
我经常看到以下三种select:
1)使用下划线的实际字段名称:
public C(Type foo_) { foo = foo_; } public void setFoo(Type foo_) { foo = foo_; }
2)使用实际的字段名称,只需在设置中使用“this”即可:
public C(Type foo) { this.foo = foo; } public void setFoo(Type foo) { this.foo = foo; }
3)完全不一致的东西,如:
public C(Type bar) { this.foo = bar; } public void setFoo(Type bar) { this.foo = bar; }
我倾向于使用2,但我想知道什么是正确的做法。
选项二是最常见的。 在Java中,使用无意义的名称前缀或后缀来区分实例variables和局部variables的参数被认为是不好的做法。 但是这些名字本身没有任何约定。 使用任何名称使代码最容易理解。
我也看到了选项2最常见的一个:
int importance; public int getImportance() { return importance; } public void setFoo(int importance) { this.importance = importance; }
Eclipse和Netbeans等IDE将自动以上述格式编写getter和setter。
使用这种方法有几个优点:
在字段名称中不要使用下划线( _
) – 下划线不build议用于非常量字段名称。
不build议在标识符中使用下划线字符,常数标识符除外。
“Java教程”的“ variables”页面提到了关于下划线的以下内容:
如果你的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代码genration使用您的列表中的样式#2。
我知道当netbeans自动创buildgetter和setter时,它使用2号方法。 我个人通常添加临时variables,即foo = tempfoo
。 但是,正如neesh所说,不pipe你select哪种方法,你都应该保持一致
是选项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“看起来相同”的字体; 那么没有人会从阅读中注意到…
是的,现在你可能会看到一个警告,或者一些代码检查工具告诉你,这发生了; 当然,你的unit testing应该立即find它。
但是:如果你避免这种模式,并使用前缀或“thatString”,你将永远不会遇到这个问题。 所以我真的不明白为什么这么常用。
所以,我们坐在我们的团队,当我们编写的编码风格指南,我们说:从来没有使用选项2。
选项2是大多数Java风格指南推荐的。
我发现Google的Java风格指南非常有用:
https://google-styleguide.googlecode.com/svn/trunk/javaguide.html#s5.2.6-parameter-names
我个人使用foo(Bar parBar)
虽然我知道它通常被认为是不好的做法foo(Bar parBar)
或后缀的variables名称。
背后的原因很简单: 清晰
现在,如果你调用一个方法foo(Bar bar)
,它实际上可能并不总是直观的。 即使是这样,它仍然是一个痛苦的屁股。
如何this.bar = bar
,甚至bar = bar
清洁,比bar = parBar
更直观? 我宁愿有一个前缀比逻辑含糊。
当你编写界面的时候,我总是喜欢在内部使用一个字段作为_name
,把它作为一个方法参数的name
,把它作为_name = name
优雅的分配。 我已经在福勒的重构和其他类似的教科书中看到了这个,尽pipe我看到丑陋的机制,例如使用字段作为内部name
然后使用aName
作为方法参数, aName
。
选项二。
如果你看到一个“setFoo(String foo)”的定义(例如在javadoc或hover中),你可以合理地预期字段“foo”被设置为参数“foo”的值。 其他的名字可能会要求你仔细检查 – 例如,setName(String person)只是将名字设置为person或者是否会采取额外的动作(在人物表格中查找名字等)?
不这样做的通常原因是,你可能会不经意地写信
… foo = foo;
代替
this.foo = foo;
这是参数的自分配,不做任何事情。 现代的编译器可以捕捉到这一点 – 现代的IDE在为字段创buildsetter时会生成“this.foo = foo”语句。
在Eclipse中,您可以为字段创buildgetter和setter,当光标位于所涉及的字段上时,使用Ctrl-1创build。
我用的约定是用m_前面的成员variables; 如下所示:
String m_foo;
这样,很清楚哪些variables是成员,哪些不是成员。
另外,我最后一家公司以“the”的方法开头,
public doFoo(String theKey,String theRandom){
….
}
这使得不容易混淆内部variables的论据。
约定应该是使代码更容易阅读,并减less错误。
选项2在Java中最为常见,但挑剔的Checkstyle不会让您使用此选项,因为本地var的名称会影响其他选项。
因为大多数使用以下内容:
foo(int thatBar) { this.bar = thatBar; }
使用这个选项的唯一问题是别人可能会猜测你在你的类中使用了一个var命名栏,因为如果没有,你不会命名这个参数。
一个邪恶的人可以使用这些信息,只有通过查看方法才能更好地理解你的课程。 但为此,你会使用一个混淆器,重命名所有的variables等