命名規則:最終フィールド(静的ではない)


23

今日はfinal、Javaクラスのフィールドの命名について同僚と話し合いました。

彼の意見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;

    ...
}

彼は私よりもはるかに経験豊富なプログラマーであり、私は彼の意見に同意し、彼を非常に優れた開発者と見なしているため、今は少し不確かです。

これに関する入力はありますか?


あなたの例は定数ではありません。コンパイル時に値を割り当てていません。エルゴ、彼らは定数の命名規則に従っていません。
ロバートハーヴェイ

@RobertHarveyありがとう、あなたは正しい。...設定の任意の可能なコンストラクタ象徴するものだったfinalフィールドを、それがために、明らかにはできませんstatic finalフィールド。
サシャ・ウルフ

1
@Zeeker static { }は、クラスがロードされたときにクラス内に静的フィールドを設定するために使用できるブロックに興味があるかもしれません。関連Javaの静的コンストラクターの操作

@RobertHarvey私はそれらに精通しています。しかし、それでも感謝します。
サシャ・ウルフ

1
変数はインスタンスに属しているため、インスタンスごとに異なるため、定数としては適用されません。キャメルケースを使用します。
フロリアンF 14

回答:


20

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つの単語のみで構成されている場合は、その単語をすべて小文字で綴ってください。複数の単語で構成される場合は、後続の各単語の最初の文字を大文字にします。名前gearRatiocurrentGearは、この規則の主要な例です。変数になどの定数値が格納されている場合、static final int NUM_GEARS = 6規則はわずかに変更され、すべての文字が大文字になり、後続の単語がアンダースコア文字で区切られます。慣例により、アンダースコア文字は他の場所で使用されることはありません。

Java用の多くの静的アナライザーは、これを強制しようとします。たとえば、checkstyleは次を強制します。

定数名がformatプロパティで指定された形式に準拠していることを確認します。定数は、静的および最終フィールドまたはインターフェイス/注釈フィールドであることを除いserialVersionUIDserialPersistentFields。形式は正規表現で、デフォルトは^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$です。


これは本当にコードを書くコミュニティの慣習に帰着します...そして理想的にはそれを同じに保ちます。

上記の例はstatic final、Cの規則から派生した可能性が高いものとして示されています。Cの#defineように、実行時ではなくコンパイル時にコード内で置き換えられます。

次に尋ねられる質問は、「これは定数のように振る舞うのか、それとも1回だけ書き込みフィールドのように振る舞うのか」です。-そして、それに応じて規則に従います。このような質問に対するリトマステストは、「オブジェクトをシリアル化する場合、最終フィールドを含めますか?」です。答えが定数である場合は、それをそのように扱います(シリアル化しないでください)。一方、シリアル化する必要があるオブジェクトの状態の一部である場合、それは定数ではありません。

いずれにせよ、それが正しいか間違っているかにかかわらず、コードスタイルを守ることが重要です。さらに悪い問題は、単に目を傷つけるものよりも、プロジェクト内の一貫性のない慣習から発生します。いくつかの静的分析ツールを入手し、一貫性を維持するように構成することを検討してください。



@RobertHarveyインスタンスフィールドが定数のように動作しているいくつかの状況を想像できます。たとえば、ファクトリでは、そうでなければオブジェクトの定数となるものを入力しますが、これらは、なぜ人がそれを行うのかを考えるだけで頭を痛めるかなり不自然な例になります。

この詳細な回答をありがとう。オブジェクトのシリアル化についてのリトマステストは、私に取り引きをしました。
サシャウルフ14

同僚は、かつて、編集者は静的/静的ファイナルなどを強調するのがあまり得意ではなかったため、この命名規則が重要であると言った有効なポイントを最近作成しました。最近のIDEは非常に優れているため、たとえば、:のMinWidth代わりに、より見栄えの良い名前を付けることができMIN_WIDTHます。もう1つの質問は、静的最終ロガーはどうでしょうか?それらをLOG/ LOGGERまたはlog/ と呼びますかlogger。個人的にlogは、コードとインラインで見た目は良くなりますが、矛盾があったとしても、許容できるのはいつですか?
ndtreviv

5

BAR_BATZこの例では定数ではありません。のコンストラクタはFoo、オブジェクトレベルで異なる値に設定できます。例えば

public class Foo {
    private final String BAR_BATZ;

    Foo() {
       BAR_BATZ = "ascending";
    } 

    Foo(String barBatz) {
       BAR_BATZ = barBatz;
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.