Java 构造函数和简单 setter 中参数命名的最佳实践

发布于 2024-07-24 23:49:40 字数 747 浏览 3 评论 0原文

对于Java中的参数到简单的构造函数和设置器来说,是否有一个标准的可接受的约定?

我已经看到了 C++ 的答案,但是实践两个社区之间通常是不同的)

假设我有一个带有 foo 字段的 C 类。

我经常看到以下三个选项:

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,但是我想知道什么是正确的做法。

Is there a standard acceptable convention for parameters in Java to straightforward constructors and setters?

(I've seen the answer for C++, but practices are often different between the two communities)

Suppose that I have a class C with a foo field.

I have commonly seen the following three options:

1) Use the actual field name with an underscore:

public C(Type foo_)
{
   foo = foo_;
}

public void setFoo(Type foo_)
{
   foo = foo_;
}

2) Use the actual field name, just use "this" in setting:

public C(Type foo)
{
   this.foo = foo;
}
public void setFoo(Type foo)
{
   this.foo = foo;
}

3) Completely inconsistent things like:

public C(Type bar)
{
   this.foo = bar;
}
public void setFoo(Type bar)
{
   this.foo = bar;
}

I tend to use 2, but I'm wondering what's correct practice.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

云之铃。 2024-07-31 23:49:41

虽然从 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");

While returning void from a setter is common, some times returning a reference of the instance is handy:

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;
    }
}

This allows you to chain setting of values : new Foo().setValue1("A").setValue2("B");

爱,才寂寞 2024-07-31 23:49:40

选项二是最常见的。 在 Java 中,使用无意义的名称前缀或后缀来区分实例变量、参数和局部变量被认为是不好的做法。 但名称本身并没有约定。 使用任何使代码最容易理解的名称。

Option two is most common. In Java it's considered poor practice to use meaningless name prefixes or suffixes to distinguish instance variables from parameters from local variables. But there are no conventions for the names themselves. Use whatever names make the code easiest to understand.

很快妥协 2024-07-31 23:49:40

我还认为选项 2 是最常见的一种:

int importance;

public int getImportance()
{
    return importance;
}

public void setFoo(int importance)
{
    this.importance = importance;
}

Eclipse 和 Netbeans 等 IDE 会自动以上述格式编写 getter 和 setter。

使用此方法有一些优点:

在字段名称中不使用下划线 (_) 字符 - 不建议在非常量字段名称中使用下划线。

除常量标识符外,不建议在标识符中使用下划线字符。

The Java Tutorials 的 变量 页面提到了以下内容下划线:

如果你的变量存储一个常量
值,例如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 中命名参数的最常见方法。

I've also seen the Option 2 as the most common one:

int importance;

public int getImportance()
{
    return importance;
}

public void setFoo(int importance)
{
    this.importance = importance;
}

IDEs such as Eclipse and Netbeans will automatically write the getters and setters in the above format.

There are a few merits to using this method:

Does not use the underscore (_) character in the field name -- underscores are not recommended for non-constant field names.

The use of the underscore character in an identifier is not recommended except for identifiers for constants.

The Variables page of The Java Tutorials mentions the following about underscores:

If your variable stores a constant
value, such as static final int
NUM_GEARS = 6, the convention changes
slightly, capitalizing every letter
and separating subsequent words with
the underscore character. By
convention, the underscore character
is never used elsewhere.

(Emphasis added.)

Since field names are not constants, according to what is written on that page, one should not use underscores in non-constant fields.

IDEs can automatically add Javadoc comments according to the name of the parameter of the method, so having the name of the field in the parameter list would be beneficial.

The following is an example of an automatically generated Javadoc:

/**
 *
 * @param importance  <-- Parameter name in Javadoc matches
 *                        the parameter name in the code.
 */
public void setImportance(int importance)
{
    this.importance = importance;
}

Having the Javadoc reflect the name of the field has another benefit -- IDEs that have code completion can use the field name in the Javadoc in order to automatically fill out parameter names:

// Code completion gives the following:
this.getImportance(importance);

Giving meaning to the field name and parameter name will make it easier to understand what the parameter actually represents.

Those are some of the merits I can come up with at the moment, and I believe that it is most likely the most common way to naming parameters in Java.

半岛未凉 2024-07-31 23:49:40

(1) 非常C/C++。 Java 不太倾向于使用前导下划线。

我个人几乎只使用(2)。

(3) 只会让你的生活变得困难,因为很难为成员和参数想出两个有意义且简洁的名称。

(1) is very C/C++. Java doesn't tend to use leading underscores much.

I personally use (2) almost exclusively.

(3) is just making your life difficult because it can be hard to think of two meaningful yet concise names for the member and the parameter.

如梦 2024-07-31 23:49:40

我见过2和3用得最多。 也就是说,答案取决于您所贡献的代码库的可接受标准。 我认为在整个项目中保持一致比为每个 Java 开发人员提供一个“正确”答案更重要。

Eclipse 代码生成使用列表中的样式#2。

I have seen 2 and 3 used the most. That said, the answer is dictated by what the accepted standard is for the code base you are contributing to. I think it is more important to be consistent across the project than have one "right" answer for every single java developer.

Eclipse code genration uses style #2 from your list.

淤浪 2024-07-31 23:49:40

我知道当 netbeans 自动创建 getter 和 setter 时,它使用 2 号方法。 我个人通常将 temp 添加到变量中,即 foo = tempfoo。 但正如尼什所说,无论你选择哪种方法,你都应该尽量保持一致

I know that when netbeans automatically creates getters and setters it uses number 2 method. I personally usually add temp to the variable i.e foo = tempfoo. But as neesh says you should try to remain consistent regardless of which method you choose

雨轻弹 2024-07-31 23:49:40

避免阴影 是

的,选项 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。

Avoid shadowing

Yes, option 2 is most widely used; although it has a severe problem: if you have a typo in the declaration of your parameter - that might go unnoticed because of variable shadowing.

Example:

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();
  }
}

This code compiles fine; and it takes you a second to understand what is wrong in there. If you are in doubt; just print it out; take it to your coworkers and ask them what will happen if this class is compiled and executed. My guess: 75%+ will not realize that a NullPointerException will be thrown. And if you turn to a font that "looks the same" for val and va1; then nobody will notice from reading ...

Yes, nowadays you might see a warning about that, or some code checking tool tells you that this happened; and of course, your unit tests should find it immediately.

But: if you avoid this pattern, and use prefixes or "thatString" you will never hit this problem in the first place. Thus I really don't understand why it is so commonly used.

So, we sat down in our team and when putting together our coding style guide we said: never use option 2.

抹茶夏天i‖ 2024-07-31 23:49:40

我个人使用 foo(Bar parBar) ,尽管我知道在变量名前或后缀通常被认为是不好的做法。

其背后的原因非常简单:清晰度

现在,如果您调用一个方法foo(Bar bar),可能并不总是直观地知道bar实际上的意思。 即使是这样,它仍然是一个痛苦的屁股。

如何 this.bar = bar 甚至 bar = bar 更干净和更多比 bar = parBar 更直观吗? 我宁愿有一个前缀,也不愿有逻辑上的歧义。

I personally use foo(Bar parBar) although I know it is generally considered poor practice pre- or suffixing variable names.

The reason behind it is quite simple: Clarity

Now, if you call a method foo(Bar bar), it may not always be intuitive what bar is actually meant. And even if it is, it's still a pain in the butt.

How is this.bar = bar or even bar = bar cleaner and more intuitive than bar = parBar? I rather have a prefix than logical ambiguity.

浅暮の光 2024-07-31 23:49:40

选项 2 是大多数 Java 风格指南推荐的选项。

我发现 Google 的 Java 样式指南非常有用:

更新的链接(2019 年 6 月):
https://google.github.io/styleguide/javaguide.html

或搜索网页“Google Java 风格指南”

Option 2 is what most Java style guides would recommend.

I have found Google's Java Style guide pretty useful :

updated link (Jun-2019):
https://google.github.io/styleguide/javaguide.html

or search the web for "Google Java Style Guide"

烟酉 2024-07-31 23:49:40

当您编写代码以使界面尽可能清晰时,我总是更喜欢在内部使用字段作为 _name ,将其作为 name 作为方法参数,并将其优雅地分配为 <代码>_name = 名称。 我在 Fowler 的《重构》和其他类似的教科书中看到了这一点,尽管我看到了丑陋的机制,例如在内部使用字段作为 name,然后使用 aName 作为方法参数,呃。

As you code to make the interface as clear as possible, I always prefer using a field as _name internally, having it as name as a method argument, assigning it elegantly as _name = name. I have seen this in Fowler's Refactoring and other similar textbooks, though I see ugly mechanisms such as using the field as name internally then using aName as a method argument, ugh.

避讳 2024-07-31 23:49:40

选项二。

如果您看到“setFoo(String foo)”定义(例如在javadoc 或hover 中),您可以合理地预期字段“foo”被设置为参数“foo”的值。 其他名称可能需要您仔细检查 - 例如 setName(String person) 只是将名称设置为 person 还是会采取其他操作(在人员表中查找名称等)?

不这样做的通常原因是您可能不小心写了

......
富 = 富;

而不是

this.foo = foo;

这是参数的自分配,不执行任何操作。 现代编译器抓住了这一点 - 现代 IDE 在为字段创建 setter 时生成“this.foo = foo”语句。

在 Eclipse 中,您可以为字段创建 getter 和 setter,当光标位于相关字段上时使用 Ctrl-1。

Option two.

If you see a "setFoo(String foo)" definition (e.g. in javadoc or hover) you would be reasonable to expect that the field "foo" is set to the value of the parameter "foo". Other names may require you to double check - e.g. would setName(String person) just set the name to person or would additional action be taken (look up the name in a table of persons etc)?.

The usual reason for not doing so is that you may accidentially write

...
foo = foo;

instead of

this.foo = foo;

which is a self-assignment of the parameter not doing anything. Modern compilers catch this - modern IDE generates the "this.foo = foo" statement when creating a setter for a field.

In Eclipse you can create the getter and setter for a field, with Ctrl-1 when the cursor is located on the field in question.

暖风昔人 2024-07-31 23:49:40

我使用的约定是在成员变量前加上 m_; 如:

String m_foo;

这样,哪些变量是成员、哪些不是成员就非常清楚了。

另外,我的上一家公司在方法中的所有参数前面都加上了“the”,如下所示:

public doFoo(String theKey, String theRandom) {

....

}

它使得很容易不将参数与内部变量混淆。

约定应该使代码更易于阅读并减少错误。

the convention that I use is to preface member variables with m_; as in:

String m_foo;

that way, it is very clear which variables are members and which are not.

also, my last company prefaced all the arguments in a method with "the", as in:

public doFoo(String theKey, String theRandom) {

....

}

it made it very easy to not confuse the arguments with internal variables.

conventions should be about making the code easier to read, and reducing errors.

顾忌 2024-07-31 23:49:40

选项 2 在 Java 中最常见,但挑剔的 Checkstyle 不允许您使用此选项,因为本地变量的名称遮盖了另一个变量的名称。

因此,大多数使用以下内容:

foo(int thatBar) {
this.bar = thatBar;
}

使用此选项的唯一问题是其他人可能会猜测您在类中使用了名为 bar 的 var,因为如果不是,您就不会如此命名该参数。

邪恶的人只需查看方法就可以使用该信息来更好地理解您的类。
但为此,您将使用一个混淆器来重命名所有变量等。

Option 2 is most common in Java but a picky Checkstyle won't let you use this option because the name of the local var shadows the other.

Because of that most use the following:

foo(int thatBar) {
this.bar = thatBar;
}

The only problem using this option is that others may guess that you are using a var named bar in your class because if not you wouldn't name the parameter so.

An evil person could use that information to better understand your class only by looking at the methods.
But for that you would use an obfuscator which renames all vars etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文