今日、Javaクラスでのfinal
フィールドの命名について同僚と話し合いました。
彼の意見では、final
フィールドも定数と見なされます。それらの値はインスタンスの作成後に変更されないためです。
これにより、final
フィールドに次の命名規則が適用されます。
public class Foo {
private static final String BLA_BLA = "bla";
private final String BAR_BATZ;
...
}
私の意見ではstatic final
フィールドは定数と見なす必要がありますが、final
のみのフィールドは通常のcamelCase命名規則に従う必要があります。
public class Foo {
private static final String BLA = "bla";
private final String barBatz;
...
}
彼は私よりもはるかに経験豊富なプログラマーであり、私は通常彼の意見に同意し、彼を非常に優れた開発者と見なしているので、今は少し不安です。
これに関する任意の入力?
Sun(そして現在のOracle)は Javaプログラミング言語のコード規約 というタイトルのドキュメントを維持しています。これに対する最後の更新は'99でしたが、スタイルの本質ガイドラインは生き続けます。
第9章 は命名規則をカバーしています。
識別子タイプが「定数」の場合:
クラス定数とANSI定数を宣言した変数の名前は、すべてアンダースコア( "_")で区切られた単語で大文字にする必要があります。 (デバッグを容易にするため、ANSI定数は使用しないでください。)
与えられた例:
_static final int MIN_WIDTH = 4;
static final int MAX_WIDTH = 999;
static final int GET_THE_CPU = 1;
_
より最近の文書で-それはそこに落ちました。から 変数(Javaチュートリアル> Java言語>言語の基本 を学習する)==:
選択した名前が1つの単語のみで構成されている場合は、その単語のスペルをすべて小文字にします。複数の単語で構成されている場合は、後続の各単語の最初の文字を大文字にします。
gearRatio
およびcurrentGear
という名前は、この規則の主な例です。変数に_static final int NUM_GEARS = 6
_などの定数値が格納されている場合、規則はわずかに変更され、すべての文字が大文字になり、後続の単語がアンダースコア文字で区切られます。慣例により、アンダースコア文字は他の場所では使用されません。
Javaの多くの静的アナライザーはこれを強制しようとします。たとえば checkstyle は強制します:
定数名がformatプロパティで指定された形式に準拠していることを確認します。定数は、
serialVersionUID
とserialPersistentFields
を除いて、静的な最終フィールドまたはインターフェース/注釈フィールドです。形式は正規表現で、デフォルトは^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$
です。
これは、コードを書いているコミュニティの規約に要約されます。理想的には、コードを同じに保ちます。
上記の例は_static final
_として示されています。これは_#define
_のCの規則から派生している可能性が高く、Cと同様に、実行時ではなくコンパイル時にコードで置き換えられます。
次に尋ねる必要がある質問は、「これは定数のように振る舞うのですか?それとも、追記型フィールドのように振る舞うのですか?」です。 -そして、それに応じて規則に従います。このような質問に対するリトマステストは、「オブジェクトをシリアル化する場合、最後のフィールドを含めますか?」答えが定数である場合は、そのように扱います(シリアル化しないでください)。一方、シリアル化する必要のあるオブジェクトの状態の一部である場合、定数ではありません。
いずれにせよ、それが正しいか間違っているかにかかわらず、コードスタイルに固執することが重要です。目を傷つけるだけのものではなく、プロジェクト内の一貫性のない規則から、より深刻な問題が発生します。いくつかの静的分析ツールを入手して、整合性を維持するように構成することを検討してください。
BAR_BATZ
は、この例では定数ではありません。 Foo
のコンストラクターは、オブジェクトレベルで異なる値に設定できます。例えば
public class Foo {
private final String BAR_BATZ;
Foo() {
BAR_BATZ = "ascending";
}
Foo(String barBatz) {
BAR_BATZ = barBatz;
}
}