私はこのような例を見ました:
public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}
また、定数をラップして静的なfinalを宣言するConstantsクラスがあるとします。私は事実上Javaをまったく知らないので、これが定数を作成するための最良の方法であるかどうか疑問に思います。
それは完全に受け入れられます、おそらく標準さえあります。
(public/private) static final TYPE NAME = VALUE;
ここで、TYPE
は型、NAME
はスペースをアンダースコアで囲むすべて大文字の名前、そしてVALUE
は定数値です。
私は強くあなたの定数をそれら自身のクラスやインターフェースに入れないでください。
補足として、finalと宣言されていて変更可能な変数は変更することができます。ただし、変数は別のオブジェクトを指すことはできません。
例えば:
public static final Point Origin = new Point(0,0);
public static void main(String[] args){
Origin.x = 3;
}
それは正当であり、Origin
は(3、0)のポイントになります。
私は単一の定数クラスを持つことに対して強く勧めます。当時は良い考えかもしれませんが、開発者が定数を文書化することを拒否し、クラスが互いにまったく関連しない500以上の定数を含むようになると(アプリケーションのまったく異なる側面に関連している)、一般的に、定数ファイルは完全に読めなくなっています。代わりに:
定数を保持するためだけにインタフェースを使用するのは BAD PRACTICE です(Josh Blochでは 定数インタフェースパターン と命名されています)。これがJoshのアドバイスです。
定数が既存のクラスまたはインタフェースに強く結び付けられている場合は、それらをクラスまたはインタフェースに追加する必要があります。たとえば、IntegerやDoubleなどのボックスで囲まれた数値プリミティブクラスはすべて、MIN_VALUEおよびMAX_VALUE定数をエクスポートします。定数が列挙型のメンバーとして最もよく表示される場合は、 enum 型を使用してそれらをエクスポートする必要があります。それ以外の場合は、インスタンス化できないユーティリティクラスを使用して定数をエクスポートする必要があります。
例:
// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
private PhysicalConstants() { } // Prevents instantiation
public static final double AVOGADROS_NUMBER = 6.02214199e23;
public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
public static final double ELECTRON_MASS = 9.10938188e-31;
}
命名規則について
慣例により、そのようなフィールドは大文字からなる名前を持ち、単語はアンダースコアで区切られています。これらのフィールドがプリミティブ値または不変オブジェクトへの参照を含んでいることが重要です。
Effective Java(2nd edition)では、定数には静的なintの代わりにenumを使うことをお勧めします。
ここにJavaのenumに関する良い記事があります: http://Java.Sun.com/j2se/1.5.0/docs/guide/language/enums.html
この記事の最後にある質問は次のとおりです。
それで、あなたはいつenumを使うべきですか?
の答えで:
いつでもあなたは定数の固定セットが必要です
インターフェースを使わないでください。
public interface MyConstants {
String CONSTANT_ONE = "foo";
}
public class NeddsConstant implements MyConstants {
}
魅力的ですが、カプセル化に違反し、クラス定義の区別があいまいになります。
私は以下のアプローチを使います。
public final class Constants {
public final class File {
public static final int MIN_ROWS = 1;
public static final int MAX_ROWS = 1000;
private File() {}
}
public final class DB {
public static final String name = "oups";
public final class Connection {
public static final String URL = "jdbc:tra-ta-ta";
public static final String USER = "testUser";
public static final String PASSWORD = "testPassword";
private Connection() {}
}
private DB() {}
}
private Constants() {}
}
例えば、私はConstants.DB.Connection.URL
を使って定数を取得しています。それは私にとってより「オブジェクト指向」に見えます。
別のクラスで静的な最終定数を作成すると、問題が発生する可能性があります。 Javaコンパイラは実際にこれを最適化し、定数の実際の値をそれを参照するクラスに配置します。
後で 'Constants'クラスを変更し、そのクラスを参照する他のクラスでハード再コンパイルをしない場合は、使用されている古い値と新しい値の組み合わせになります。
これらを定数と考える代わりに、それらを設定パラメータと見なし、それらを管理するクラスを作成します。値が最終的でないようにし、さらにゲッターの使用を検討してください。将来的には、これらのパラメーターのいくつかがユーザーまたは管理者によって実際に構成可能であるべきだとあなたが判断したとき、それはするのがはるかに簡単になるでしょう。
あなたがすることができる一番の間違いは、Constantsのように、一般名で呼ばれるグローバルにアクセス可能なクラスを作成することです。これは単にゴミで散らばってしまい、あなたはあなたのシステムのどの部分がこれらの定数を使っているかを理解する全ての能力を失います。
代わりに、定数はそれらを「所有する」クラスに入れるべきです。 TIMEOUTという定数がありますか。それはおそらくあなたのCommunications()またはConnection()クラスに入るべきです。 MAX_BAD_LOGINS_PER_HOUR? User()に入ります。などなど。
実行時に「定数」を定義することはできますが、ユーザーが簡単に変更することはできない場合、もう1つの用途はJavaの.propertiesファイルです。これらを.jarsにパッケージ化して、それらをClass resourceLoaderで参照することができます。
それは正しい道です。
一般的に定数は発見できないので not は別々の "Constants"クラスに保存されます。定数が現在のクラスに関連している場合、それらをそこに保持すると次の開発者に役立ちます。
私は、インターフェースを使用することが目的ではないことに同意します。このパターンを避けることは、Blochの Effective Java にもそれ自身の項目(#18)があります。
Blochが定数インターフェースパターンに対して主張しているのは、定数の使用は実装の詳細であるということですが、それらを使用するためのインターフェースの実装はエクスポートされたAPIでその実装の詳細を公開します。
public|private static final TYPE NAME = VALUE;
パターンは定数を宣言する良い方法です。個人的には、すべての定数を格納するために別のクラスを作成しない方が良いと思いますが、個人的な好みやスタイル以外に、これをしない理由は見たことがありません。
定数が列挙としてうまくモデル化できる場合は、1.5以降で使用可能な enum 構造体を検討してください。
1.5より前のバージョンを使用している場合でも、通常のJavaクラスを使用して型保証された列挙をやめることができます。 (詳しくは このサイト をご覧ください)。
列挙についてはどうですか?
私は定数よりもゲッターを使うことを好みます。これらのゲッターは定数値を返すかもしれません。 public int getMaxConnections() {return 10;}
、しかし定数を必要とするものはすべてゲッターを通ります。
1つの利点は、あなたのプログラムが定数を上回る場合 - それは設定可能である必要があることがわかった - あなたは単にgetterが定数を返す方法を変更できるということです。
もう1つの利点は、定数を変更するために、それを使用するすべてのものを再コンパイルする必要がないことです。静的最終フィールドを参照すると、その定数の値はそれを参照する任意のバイトコードにコンパイルされます。
上記のコメントに基づいて、私はこれが(公共の静的な最終変数を持つ)旧式のグローバル定数クラスをこのようなenumのような等価物に変更するための良い方法だと思います。
public class Constants {
private Constants() {
throw new AssertionError();
}
public interface ConstantType {}
public enum StringConstant implements ConstantType {
DB_Host("localhost");
// other String constants come here
private String value;
private StringConstant(String value) {
this.value = value;
}
public String value() {
return value;
}
}
public enum IntConstant implements ConstantType {
DB_PORT(3128),
MAX_PAGE_SIZE(100);
// other int constants come here
private int value;
private IntConstant(int value) {
this.value = value;
}
public int value() {
return value;
}
}
public enum SimpleConstant implements ConstantType {
STATE_INIT,
STATE_START,
STATE_END;
}
}
それで、私はそれらを好きに呼ぶことができます:
Constants.StringConstant.DB_Host
良いオブジェクト指向設計は、公に利用可能な多くの定数を必要とすべきではありません。ほとんどの定数は、その役割を果たすためにそれらを必要とするクラスにカプセル化されるべきです。
これに答えるためにある程度の意見があります。まず第一に、Javaの定数は一般にpublic、staticそしてfinalであると宣言されています。以下がその理由です。
public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
makes little sense to duplicate them for every object.
final, since they should not be allowed to change
単にインターフェースが実装されることが一般的に想定されているからといって、私は決してCONSTANTSアクセサ/オブジェクトのためにインターフェースを使用することはないだろう。これはおかしくないでしょう。
String myConstant = IMyInterface.CONSTANTX;
代わりに、いくつかの小さなトレードオフに基づいて、いくつかの方法から選択します。したがって、それは必要なものによって異なります。
1. Use a regular enum with a default/private constructor. Most people would define
constants this way, IMHO.
- drawback: cannot effectively Javadoc each constant member
- advantage: var members are implicitly public, static, and final
- advantage: type-safe
- provides "a limited constructor" in a special way that only takes args which match
predefined 'public static final' keys, thus limiting what you can pass to the
constructor
2. Use a altered enum WITHOUT a constructor, having all variables defined with
prefixed 'public static final' .
- looks funny just having a floating semi-colon in the code
- advantage: you can JavaDoc each variable with an explanation
- drawback: you still have to put explicit 'public static final' before each variable
- drawback: not type-safe
- no 'limited constructor'
3. Use a Class with a private constructor:
- advantage: you can JavaDoc each variable with an explanation
- drawback: you have to put explicit 'public static final' before each variable
- you have the option of having a constructor to create an instance
of the class if you want to provide additional functions related
to your constants
(or just keep the constructor private)
- drawback: not type-safe
4. Using interface:
- advantage: you can JavaDoc each variable with an explanation
- advantage: var members are implicitly 'public static final'
- you are able to define default interface methods if you want to provide additional
functions related to your constants (only if you implement the interface)
- drawback: not type-safe
Javaで定数を実装するための最良の方法は何ですか?
我々が本当に避けるべき一つのアプローチ:定数を定義するためにインターフェースを使う。
特に定数を宣言するためのインターフェースを作成することは、本当に最悪のことです。それは、インターフェースが設計された理由、すなわちメソッドコントラクトの定義を打ち破ることを打ち負かします。
特定のニーズに対処するためのインタフェースがすでに存在していても、定数をAPIの一部にしてはならず、クライアントクラスに提供される規約を使用してはならないので、定数を宣言することは実際には意味がありません。
簡単にするために、4つの有効なアプローチがあります。
static final String/Integer
フィールドの場合:
Java 5 enum
の場合:
TLDR:どちらが最良の方法で、どこに定数がありますか?
ほとんどの場合、enumのほうがおそらくstatic final String/Integer
の方法よりも細かいです _そして個人的にはstatic final String/Integer
の方法は、enumを使用しない正当な理由がある場合にのみ使用すべきだと思います。
そして、定数値をどこで宣言すべきかについて、アイデアは、定数値を持つ特定の強力な関数結合を所有する単一の既存のクラスが存在するかどうかを検索することです。定数ホルダーとして使用する必要があります。それ以外の場合、定数は特定のクラスに関連付けないでください。
static final String
/static final Integer
とenum
列挙型の使用法は、実際に強く考慮する方法です。
列挙型はString
またはInteger
定数フィールドよりも大きな利点があります。
彼らはより強い編集制約を設定しました。 enumをパラメータとするメソッドを定義した場合は、enumクラスで定義されたenum値のみを渡すことができます(またはnull)。
StringとIntegerを使えば、互換性のある型の値に置き換えることができ、値がstatic final String
/static final Integer
フィールドで定義された定数でなくてもコンパイルは問題ありません。
たとえば、クラス内でstatic final String
フィールドとして定義されている2つの定数は、以下のとおりです。
public class MyClass{
public static final String ONE_CONSTANT = "value";
public static final String ANOTHER_CONSTANT = "other value";
. . .
}
ここで、パラメータとしてこれらの定数の1つを持つことを期待しているメソッド:
public void process(String constantExpected){
...
}
このようにして呼び出すことができます。
process(MyClass.ONE_CONSTANT);
または
process(MyClass.ANOTHER_CONSTANT);
しかし、コンパイル制約がないため、このようにして呼び出すことができません。
process("a not defined constant value");
あなたは実行時にだけ、そしてあなたが一度に送信された値のチェックをした場合にのみエラーがあるでしょう。
Enumでは、クライアントはenumパラメータにenum値を渡すことしかできないため、チェックは不要です。
たとえば、ここでは2つの値がenumクラスで定義されています(そのまま箱から出して定数):
public enum MyEnum {
ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");
private String value;
MyEnum(String value) {
this.value = value;
}
...
}
ここで、これらの列挙値の1つをパラメータとして持つことを期待しているメソッド:
public void process(MyEnum myEnum){
...
}
このようにして呼び出すことができます。
process(MyEnum.ONE_CONSTANT);
または
process(MyEnum.ANOTHER_CONSTANT);
しかし、コンパイルでは、このようにして呼び出すことはできません。
process("a not defined constant value");
どこで定数を宣言すべきですか?
アプリケーションに、定数値を使用した特定の強力な機能的結合を所有する単一の既存クラスが含まれている場合は、1)と2)がより直感的に見えます。
一般に、定数がそれらを操作するメインクラスで宣言されているか、内部で見つかると推測するのに非常に自然な名前が付けられている場合、定数の使用は容易になります。
たとえばJDKライブラリでは、指数およびπの定数値は、定数宣言だけではなく宣言するクラス(Java.lang.Math
)で宣言されています。
public final class Math {
...
public static final double E = 2.7182818284590452354;
public static final double PI = 3.14159265358979323846;
...
}
数学関数を使用しているクライアントはしばしばMath
クラスに頼ります。そのため、彼らは十分に簡単に定数を見つけることができ、E
とPI
が非常に自然な方法で定義されている場所を思い出すこともできます。
あなたのアプリケーションが、定数値を持つ非常に具体的で強力な機能的結合を持つ既存のクラスを含んでいない場合は、1)と2)の方法がより直感的に見えます。
一般的に、定数をそれらを操作する1つのクラスで宣言しても、定数を使用するのは簡単ではありません。ホスト定数値に対して他のものよりも自然です。
ここでは、定数値のみを保持するようにカスタムクラスを定義するのが合理的です。
例えば、JDKライブラリでは、Java.util.concurrent.TimeUnit
列挙型は特定のクラスで宣言されていません。それを保持するのが最も直感的にわかるようなJDK固有のクラスが実際には1つしかないからです。
public enum TimeUnit {
NANOSECONDS {
.....
},
MICROSECONDS {
.....
},
MILLISECONDS {
.....
},
SECONDS {
.....
},
.....
}
Java.util.concurrent
で宣言されている多くのクラスはそれらを使用します:BlockingQueue
、ArrayBlockingQueue<E>
、CompletableFuture
、ExecutorService
、...そしてそれらのどれもenumを保持するのにより適切ではないようです。
ちなみに、秒単位のタイムアウト値はおそらく構成設定(プロパティー・ファイルから読み込まれるか、Springのようにインジェクションを通じて)であり、定数ではありません。
違いはなんですか
1。
public interface MyGlobalConstants {
public static final int TIMEOUT_IN_SECS = 25;
}
2。
public class MyGlobalConstants {
private MyGlobalConstants () {} // Prevents instantiation
public static final int TIMEOUT_IN_SECS = 25;
}
そして、この定数が必要なところではどこでもMyGlobalConstants.TIMEOUT_IN_SECS
を使います。どちらも同じだと思います。
単一の総称定数クラスは悪い考えです。定数は、それらが最も論理的に関連しているクラスと一緒にグループ化されるべきです。
あらゆる種類の変数(特に列挙型)を使用するのではなく、メソッドを使用することをお勧めします。変数と同じ名前のメソッドを作成し、変数に割り当てた値を返すようにします。今すぐ変数を削除し、作成したメソッドへの呼び出しで変数へのすべての参照を置き換えます。定数が一般的なもので、使用するだけでクラスのインスタンスを作成する必要がないと思われる場合は、定数メソッドをクラスメソッドにします。
任意の型の定数は、クラス内の不変プロパティ(つまり、final
修飾子を持つメンバ変数)を作成することによって宣言できます。通常static
およびpublic
修飾子も提供されています。
public class OfficePrinter {
public static final String STATE = "Ready";
}
定数の値が選択のnタプル(例えば、enumeration)からの選択を示す多くの用途がある。この例では、可能な割り当て値を制限する列挙型を定義することを選択できます(つまり、type-safetyの向上)。
public class OfficePrinter {
public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
public static final PrinterState STATE = PrinterState.Ready;
}
このクラスを定数と同じ(大文字と小文字の区別を除く)とは呼ばないでしょう...少なくともすべての定数が存在する、 "Settings"、 "Values"、または "Constants"の少なくとも1つのクラスがあります。それらが多数ある場合は、それらを論理定数クラス(UserSettings、AppSettingsなど)にグループ化します。
static final
が私の好みです。アイテムが本当に列挙可能であれば、enum
を使うだけです。
基本的なゼロからゼロの原理主義を理解せずにJoshua Blochを引用するのは悪い習慣でひどくANNOYINGの練習です。
Joshua Blochは何も読んでいないので、
聖書原理主義と同様に、すべての聖書の法則は以下のようにまとめることができます。
そして同様にソフトウェア工学の原理主義は次のようにまとめることができます。
また、聖書原理主義者サークルの中には、強く合理的な推論が描かれています。
同様に、あなたがプログラマーであることを尊重しないで、基礎を疑問に思うことなくプログラミングの専門家達の発言や予言を受け入れるだけなら、あなたの引用やJoshua Bloch(など)への信頼は無意味です。それゆえ、あなたは実際にはあなたの仲間のプログラマーを尊敬しないでしょう。
ソフトウェアプログラミングの基本法則
根本的に効果的で責任あるプログラミングのどの法律の下でこの宗教的な叙述は陥りますか?
インターフェースパターン定数に関するウィキペディアの記事( https://en.wikipedia.org/wiki/Constant_interface )を読むだけで、インターフェースパターン定数に対して愚かな言い訳がされています。
Whatif - いいえIDE?ソフトウェアプログラマーとして誰がIDEを使わないのでしょうか。私たちのほとんどは、IDEの使用を回避することによってマッチョな無神論的生存主義を持つことを証明する必要がないことを好むプログラマです。
現在のスコープ内で使用されていない変数で名前空間を汚染しますか?それはこの意見の支持者かもしれません
定数を強制するためにインターフェースを使用することは、インターフェースの悪用です。そのような支持者はの悪い習慣を持っています
将来、インタフェースを実装クラスに変換することは不可能ではないにしても困難です。うーん……うーん……?
たとえどんな言い訳でも、それが基本的に効果的なソフトウェアエンジニアリングに関しては、インターフェース定数の使用を非公式にするか、一般的に推奨しないことには正当な言い訳はありません。
それは、合衆国憲法を作り上げた創設者の父親の当初の意図と精神状態が何であったかは関係ありません。私たちは創設した父親の当初の意図について議論することができましたが、私が気にしているのは米国憲法の書面による声明だけです。そしてそれは、米国憲法の文書化されていない創設意図ではなく、文書化された文学原理主義を利用することがすべての米国市民の責任です。
同様に、私は、Javaプラットフォームとプログラミング言語の創設者の「元々の」意図がインターフェースに対して持っていたことを気にしません。私が気にしているのは、Java仕様が提供する効果的な機能です。これらの機能を最大限に活用して、責任あるソフトウェアプログラミングの基本的な法則を満たすのに役立ちます。 「インターフェースの意図に違反する」と感じても構わない。 Goslingや他の誰かが "Javaを使うための適切な方法"について何を言っていても、私がEFFECTIVEを満たすための基本を満たすための必要性を侵害していないのであれば、構いません。
データモデルがどのようにホストまたは送信されているかは関係ありません。データモデルの正規化の必要性とプロセスを理解していない場合は、インターフェースまたは列挙型を使用しているかどうかにかかわらず、リレーショナルかSQLなしかを問わず使用できます。
最初に、一連のプロセスのデータモデルを定義して正規化する必要があります。コヒーレントなデータモデルがあるときには、そのコンポーネントのプロセスフローを使用して機能的な振る舞いを定義し、プロセスがアプリケーションの分野や分野をブロックすることしかできません。そしてそのとき初めて、各機能プロセスのAPIを定義することができます。
EF Coddによって提案されたようなデータ正規化の面でさえ、今や厳しく挑戦され、そして厳しく挑戦されています。例えば彼の1NFに関する声明は、特に現代のデータサービス、レポテクノロジーおよび伝送の出現における残りの声明と同様に、あいまいで、位置ずれがあり、単純化されすぎていると批判されてきた。 IMO、EF Coddステートメントは完全に廃止され、より数学的にもっともらしいステートメントの新しいセットが設計されるべきです。
EF Coddの明白な欠陥と人間の効果的な理解に対するそのずれの原因は、人間が知覚できる多次元の可変次元データが、断片的な2次元マッピングのセットを通して効率的に知覚されるという彼の信念です。
EF Coddが表現できなかったこと.
各コヒーレントデータモデル内で、これらは達成すべきデータモデルコヒーレンスの逐次段階的順序である。
サービス間のコンポーネントアプリケーションの分野またはグリッドでは、唯一のコヒーレントデータモデルがなければならないか、またはデータモデル/バージョンがそれ自体を識別するための手段が存在する。
この平凡な質問よりも結果的に危険にさらされているデータ正規化問題があります。あなたがそれらの問題を解決しないならば、あなたがインターフェース定数が引き起こすと思う混乱は比較的なにもありません。 Zilch.
データモデルの正規化から、コンポーネントを変数、プロパティ、コントラクトインターフェイス定数として決定します。
次に、どちらが値の注入、プロパティ設定のプレースホルダ、インターフェイス、最終文字列などに入るかを決定します。
インターフェース定数に対して指示しやすいコンポーネントを探す必要があるという言い訳をしなければならない場合は、データモデルの正規化を行わないという悪い習慣があります。
おそらくあなたはデータモデルをvcsリリースにコンパイルしたいと思うでしょう。データモデルの明確に識別可能なバージョンを引き出すことができます。
インターフェースで定義された値は、変更不可能であることが完全に保証されています。そして共有可能です。あなたが必要としているのが定数のそのセットだけなのに、なぜ別のクラスからあなたのクラスに一連の最終文字列をロードするのでしょうか。
それでは、これでデータモデル契約を公開しないのはなぜでしょうか。私はあなたがそれを首尾一貫して管理し正規化することができれば、なぜですか? ...
public interface CustomerService {
public interface Label{
char AssignmentCharacter = ':';
public interface Address{
String Street = "Street";
String Unit= "Unit/Suite";
String Municipal = "City";
String County = "County";
String Provincial = "State";
String PostalCode = "Zip"
}
public interface Person {
public interface NameParts{
String Given = "First/Given name"
String Auxiliary = "Middle initial"
String Family = "Last name"
}
}
}
}
これで、アプリの契約ラベルを次のような方法で参照できます。
CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family
これはjarファイルの内容を混乱させるのですか? Javaプログラマーとして、私はjarファイルの構造を気にしません。
これはosgiに動機付けられたランタイムスワッピングの複雑さを表していますか? Osgiは、プログラマーが悪い習慣を続けられるようにするための非常に効率的な手段です。 osgiよりも優れた選択肢があります。
それともどうしてですか?公開された契約への私的定数の漏洩はありません。私は定数を検索する必要はありませんし、「private final String」を繰り返し入力するのは面倒なので、すべてのプライベート定数は「Constants」という名前のプライベートインターフェイスにグループ化する必要があります。
public class PurchaseRequest {
private interface Constants{
String INTERESTINGName = "Interesting Name";
String OFFICIALLanguage = "Official Language"
int MAXNames = 9;
}
}
おそらくこれさえ:
public interface PurchaseOrderConstants {
public interface Properties{
default String InterestingName(){
return something();
}
String OFFICIALLanguage = "Official Language"
int MAXNames = 9;
}
}
考慮に値するインタフェース定数に関する唯一の問題は、インタフェースが実装されている場合です。
これはインターフェースの「本来の意図」ではありませんか。私が最高裁判所が米国憲法の書面による手紙を解釈する方法よりもむしろ、米国憲法を作成する際の創設者の父親の「本来の意図」を気にするように?
結局のところ、私は勇者の自由、野生そして家の土地に住んでいます。勇敢になり、自由になり、ワイルドになりましょう - インターフェースを使ってください。私の仲間のプログラマーが効率的で怠惰なプログラミング手段の使用を拒否した場合、私は自分のプログラミング効率を低下させるという黄金律を義務付けていますか。おそらく私はすべきですが、それは理想的な状況ではありません。
さらに一歩進めて、グローバルに使用される定数をインターフェイスに配置して、システム全体で使用できるようにすることができます。例えば。
public interface MyGlobalConstants {
public static final int TIMEOUT_IN_SECS = 25;
}
しかし、それを実装しないでください。完全修飾クラス名を介してコード内で直接参照するだけです。
私はstatic final
を使って定数を宣言し、ALL_CAPS命名法を使います。私は、すべての定数が1つのインターフェースにまとめられている実生活の例をかなり見ました。いくつかの投稿では、それが悪い習慣だと正しく主張しています。それは、主にそれがインターフェースの目的ではないためです。インターフェイスはコントラクトを強制するべきであり、関係のない定数を入れる場所にすべきではありません。インスタンス化できないクラスにそれをまとめる(プライベートコンストラクタを通して)こともできません。 es)私はいつもそれが最も関連しているクラスに定数を入れました。
列挙型は値の範囲を表すのに適していますが、絶対値を重視してスタンドアロンの定数を保存する場合(たとえばTIMEOUT = 100 ms)、static final
アプローチを使用することができます。
定数の場合、Enumはより良い選択です。これが例です
パブリッククラスmyClass {
public enum myEnum {
Option1("String1", 2),
Option2("String2", 2)
;
String str;
int i;
myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }
}
私はほとんどの人が言っていることに同意します。定数の集まりを扱うときはenumを使うのが最善です。あなたがAndroidでプログラミングしている場合は、より良い解決策があります: IntDef Annotation 。
@Retention(SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(@NavigationMode int mode);
@NavigationMode
public abstract int getNavigationMode();
IntDefアノテーションは、単純な点でenumよりも優れています。コンパイル時のマーカーであるためスペースが大幅に少なくなります。これはクラスではなく、自動文字列変換プロパティもありません。
私が行う方法の1つは、定数値を使って「Global」クラスを作成し、その定数にアクセスする必要があるクラスで静的インポートを実行することです。