Best practice for parameter naming in Java constructors and simple setters

寵の児 提交于 2019-11-26 20:47:45

问题


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.


回答1:


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.




回答2:


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.




回答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.




回答4:


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.




回答5:


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




回答6:


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.




回答7:


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 shadowing, like:

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.




回答8:


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"




回答9:


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.




回答10:


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.




回答11:


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.




回答12:


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.




回答13:


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");



来源:https://stackoverflow.com/questions/991757/best-practice-for-parameter-naming-in-java-constructors-and-simple-setters

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!