Javaのパラメーターの単純なコンストラクターとセッターに対する標準の受け入れ可能な規則はありますか?
( C++の答えを見てきました ですが、2つのコミュニティ間で慣例が異なることがよくあります)
Fooフィールドを持つクラスCがあるとします。
私は一般的に次の3つのオプションを見てきました。
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を使用する傾向がありますが、何が正しい練習なのかと思っています。
オプション2が最も一般的です。 Javaでは、意味のない名前の接頭辞または接尾辞を使用して、インスタンス変数とパラメータをローカル変数から区別することはお勧めできません。ただし、名前自体に規則はありません。コードを最も簡単にする名前を使用してください。理解する。
オプション2を最も一般的なものとしても見ました。
int importance;
public int getImportance()
{
return importance;
}
public void setFoo(int importance)
{
this.importance = importance;
}
EclipseやNetbeansなどのIDEは、上記の形式でゲッターとセッターを自動的に書き込みます。
この方法を使用するメリットはいくつかあります。
フィールド名にアンダースコア(_
)文字を使用しません-非定数フィールド名にはアンダースコアを使用しないでください。
定数の識別子を除いて、識別子にアンダースコア文字を使用することはお勧めしません。
Javaチュートリアルの 変数 ページでは、アンダースコアについて次のように述べています。
変数に
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にフィールドの名前を反映させると、もう1つの利点があります-コード補完のあるIDEは、Javadocのフィールド名を使用して、パラメータ名を自動的に入力できます:
// Code completion gives the following:
this.getImportance(importance);
フィールド名とパラメーター名に意味を与えると、パラメーターが実際に何を表すかを理解しやすくなります。
これらは、私が現時点で思いつくメリットの一部であり、Javaでパラメーターに名前を付ける最も一般的な方法であると私は考えています。
(1)は非常にC/C++です。 Javaは、先頭のアンダースコアをあまり使用しない傾向があります。
私は(2)をほぼ独占的に使用しています。
(3)は、メンバーとパラメーターの2つの意味のある簡潔な名前を考えるのが難しい場合があるため、単にあなたの人生を難しくしています。
2と3が最も使用されているのを見ました。とはいえ、その答えは、あなたが貢献しているコードベースの受け入れられた標準が何であるかによって決まります。 Java開発者ごとに1つの「正しい」答えを持つよりも、プロジェクト全体で一貫していることが重要です。
Eclipseコード生成では、リストのスタイル#2を使用します。
Netbeansが自動的にゲッターとセッターを作成するとき、2番目の方法を使用することを知っています。私は通常、変数にtempを追加します。つまり、foo = tempfoo
。しかし、ニーシュが言うように、どの方法を選択しても、一貫性を保つように努めるべきです
オプション2は、ほとんどのJavaスタイルガイドが推奨するものです。
私はGoogleのJava=スタイルガイドがかなり便利だと感じました:
更新されたリンク(2019年6月): https://google.github.io/styleguide/javaguide.html
または「Google Java Style Guide」をウェブで検索してください
はい、オプション2が最も広く使用されています。それは深刻な問題があります:パラメータの宣言にタイプミスがある場合-shadowingのために気付かれないかもしれません:
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がスローされることをnotが認識します。そして、valとva1が「同じに見える」フォントを使用すると、その後、誰も読んで気づかないでしょう...
はい、今日では、そのことに関する警告が表示されるか、一部のコードチェックツールでこれが発生したことが通知されます。そしてもちろん、単体テストはすぐにそれを見つけるはずです。
しかし、このパターンを回避し、接頭辞または「thatString」を使用すると、最初からこの問題に遭遇することはありません。したがって、なぜそれがそれほど一般的に使用されているのかは本当にわかりません。
したがって、私たちはチームに座って、コーディングスタイルガイドをまとめるときに、オプション2は使用しないでください。
個人的にはfoo(Bar parBar)
を使用しますが、変数名の前後に接尾辞を付けることは一般的に不適切であると考えられています。
その背後にある理由は非常に簡単です:明快さ
ここで、メソッドfoo(Bar bar)
を呼び出す場合、bar
が何を意味するか実際にはが直感的であるとは限りません。 そうであっても、それはまだお尻の痛みです
this.bar = bar
あるいは bar = bar
よりクリーンで直感的bar = parBar
?私は論理的な曖昧さよりも接頭辞を持っています。
オプション2は、Javaで最も一般的ですが、ローカル変数の名前が他の変数を隠すため、うるさいCheckstyleでは、このオプションを使用できません。
そのため、ほとんどは以下を使用します。
foo(int thatBar) { this.bar = thatBar; }
このオプションを使用する唯一の問題は、クラスにvarという名前のバーを使用していると他の人が推測する可能性があることです。
悪意のある人は、メソッドを見るだけで、その情報を使用してクラスをよりよく理解できます。しかし、そのためには、すべての変数などの名前を変更する難読化ツールを使用します。
私が使用する規則は、メンバー変数の前にm_を付けることです。のように:
文字列m_foo;
そうすれば、どの変数がメンバーでどれがメンバーではないかが非常に明確になります。
また、私の最後の会社は、メソッドのすべての引数の前に「the」を付けました。
public doFoo(String theKey、String theRandom){
....
}
引数を内部変数と混同しないようにするのは非常に簡単でした。
規約は、コードを読みやすくし、エラーを減らすことです。
インターフェイスをできるだけ明確にするためにコーディングするときは、フィールドを内部で_name
として使用し、メソッド引数としてname
として使用し、_name = name
としてエレガントに割り当てます。 Fowlerのリファクタリングや他の同様の教科書でこれを見たことがありますが、フィールドを内部でname
として使用し、メソッドの引数としてaName
を使用するなどの醜いメカニズムを見ています。
オプション2。
「setFoo(String foo)」の定義が表示された場合(javadocやホバーなど)、フィールド「foo」がパラメータ「foo」の値に設定されていると想定するのが妥当でしょう。他の名前では、再確認が必要になる場合があります。 setName(String person)は名前をpersonに設定するだけですか、それとも追加のアクションを実行しますか(人のテーブルなどで名前を検索します)。
そうしない通常の理由は、誤って書く可能性があるためです
... foo = foo;
の代わりに
this.foo = foo;
これは、何もしないパラメータの自己割り当てです。現代のコンパイラはこれをキャッチします-現代のIDEは、フィールドのセッターを作成するときに「this.foo = foo」ステートメントを生成します。
Eclipseでは、カーソルが問題のフィールド上にあるときにCtrl-1を使用して、フィールドのゲッターとセッターを作成できます。
セッターから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");