私は、人々がpublic static final String mystring = ...
を書いてから値を使用するコードを見てきました。
なぜそうしなければならないのですか?使用する前に値をfinal
として初期化する必要があるのはなぜですか?
UPDATE
わかりました、あなたのすべての答えに感謝します、私はそれらのキーの意味を理解します(public static final)。私が理解していないのは、定数が同じ場所でのみ使用される場合でも、人々がそれを使用する理由です。なぜそれを宣言するのですか?なぜ変数を使用しないのですか?
final
は、変数の値が変更されないこと、つまり、宣言された後に値を変更できない変数を示します。
以下を行うString
を作成する場合は、public final static String
を使用します。
static
:使用するためのインスタンスは不要)、そしてfinal
定数を定義する場合など、変更されません(String
)。例:
public final static String MY_CONSTANT = "SomeValue";
// ... in some other code, possibly in another object, use the constant:
if (input.equals(MyClass.MY_CONSTANT)
同様に:
public static final int ERROR_CODE = 127;
final
を使用することは必須ではありませんが、プログラムの実行中に定数が不注意に変更されるのを防ぎ、変数が定数であることの指標として機能します。
定数が現在のクラスおよび/または1箇所でのみ使用される場合でも、すべての定数をfinal
として宣言することをお勧めします。より明確で、コードの有効期間中に定数を複数の場所で使用されることになります。
さらに、final
を使用すると、実装で何らかの最適化を実行できる場合があります。定数が使用される実際の値をインライン化する。
final..Itは、文字列を一定にするために使用されるキーワードです。その文字列の値を変更することはできません。以下の例を見てください:
public class StringTest {
static final String str = "Hello";
public static void main(String args[]) {
// str = "world"; // gives error
System.out.println(str); // called without the help of an object
System.out.println(StringTest.str);// called with class name
}
}
ありがとう
キーワードfinalは、値が定数であることを意味します(変更できません)。 Cのconstに似ています。
そして、staticをスコープを持つグローバル変数として扱うことができます。基本的には、1つのオブジェクトに対して変更すると、グローバル変数のように(スコープによって制限される)すべてのオブジェクトに対して変更されます。
それが役に立てば幸い。
final
は、一度設定すると値を変更できないことを示します。 static
を使用すると値を設定でき、その値はそれを使用するクラスのすべてのインスタンスで同じになります。また、クラスのインスタンスがないpublic static
文字列の値にアクセスすることもできます。
static
は、オブジェクトが1回だけ作成され、それを含むインスタンスオブジェクトがないことを意味します。あなたが書いた方法は、クラスのすべてのオブジェクトに共通で、決して変わらないものがある場合に最もよく使用されます。オブジェクトをまったく作成せずに使用することもできます。
通常、finalをfinal
であることが予想される場合は、finalを使用するのが最善です。これにより、コンパイラーがその規則を実施し、確実にわかるようになります。 static
は、すべてのオブジェクトで同じ値になる場合にメモリを浪費して同じものを作成しないようにします。
通常、定数を定義するために、多くの場所で再利用して、変更のための単一のポイントにし、単一のクラス内で使用するか、パッケージ間で共有します。変数をfinalにすると、偶発的な変更を回避できます。
publicは、他のクラス全体でアクセスできるようにします。クラスをインスタンス化せずに、またはオブジェクトを使用せずに使用できます。
staticは、すべてのクラスインスタンスで値を統一します。すべてのオブジェクトで同じ値になる場合、メモリを無駄にして同じものを作成しないようにします。
最終は、変更不可能な値にします。これは、すべてのクラスインスタンスで同じであり、変更できない「定数」値です。
それは一種の標準/ベストプラクティスです。シナリオをリストする回答は既にありますが、2番目の質問については:
なぜそうしなければならないのですか?使用する前に値を最終として初期化する必要があるのはなぜですか?
宣言時に初期化されるパブリック定数とフィールドは、単に「最終」ではなく「静的最終」である必要があります
これらの理由は次のとおりです。
静的ファイナルではなく、パブリック定数をファイナルファイナルにすると、クラスのすべてのインスタンスの値が重複し、アプリケーションの実行に必要なメモリ量が無駄に増加します。
さらに、非公開の最終フィールドも静的ではない場合、異なるインスタンスが異なる値を持つ可能性があることを意味します。ただし、宣言で非静的な最終フィールドを初期化すると、 final フィールドの動作により、すべてのインスタンスが同じ値を持つようになります。
public
は、他のクラス間でアクセスできるようにします。 static
は、すべてのクラスインスタンスで値を統一します。 final
は、変更不可能な値にします。したがって、基本的には、「constant」値であり、すべてのクラスインスタンスで同じであり、変更できません。あなたの懸念に関して「私が理解していないのは、同じ定数が同じクラスでのみ使用される場合でも、人々がそれを使用する理由です。なぜそれを宣言するのですか?なぜ変数を使用しないのですか?」パブリックフィールドであるため、ClassName.valueを使用して、定数値を他のクラスの他の場所で使用することもできます。例:Mathという名前のクラスは、Math.PIとしてアクセスできる最終的な静的なlong値としてPIを持つことができます。
なぜ人々は変数の代わりにクラスで定数を使用するのですか?
読みやすさと保守性、
コードに40.023のような数字が含まれていても、その数字が何を表すかについてはあまり言及していないため、「USER_AGE_YEARS」のような大文字のWordに置き換えます。後でコードを見ると、その数字が何を表しているかが明確になります。
なぜ変数を使用しないのですか?番号が変更されることがわかっていればそうですが、3.14159のように変更されない番号がある場合は、最終的に変更します。
しかし、文字列のような数値ではない場合はどうでしょうか?その場合、主に保守性のために、コード内で文字列を複数回使用している場合(および実行時に変更されない場合)、クラスの最上部の最終文字列として使用すると便利です。そのように変更したい場合、変更するのは多くの場所ではなく1つの場所だけです。
たとえば、コードに何度も出力されるエラーメッセージがあり、最終的な文字列がERROR_MESSAGE = "Something goes bad。"である場合「何かがうまくいかなかった」から変更したい場合は、保守が簡単です。 「彼はすでに死んでいるジムでは遅すぎます」に、あなたはそのコメントを使用するすべての場所ではなく、その1行だけを変更する必要があります。
have to use final
ではありませんが、final
は、コンパイラを含む他のすべての人に、これが定数であり、それが良い習慣であることを明らかにしています。
なぜ人々がそれを行うのか定数が1つの場所と同じクラスでのみ使用される場合でも:多くの場合、それはまだ理にかなっているからです。たとえば、プログラムの実行中に最終的なものになることがわかっているが、後で値を変更して再コンパイル(見つけやすく)することを意図しており、後で頻繁に使用することもあります。また、他のプログラマーにプログラムフローの主要な価値について、目立つ場所と組み合わせた場所で知らせています。
残念ながら、他の答えが欠けている側面は、public final
の組み合わせを使用する必要があることです非常に慎重に。特に、他のクラスまたはパッケージがクラスを使用する場合(想定される場合) public
)であるためです。
その理由は次のとおりです。
final
として宣言されているため、コンパイラーは、コンパイル時にこのフィールドを読み取るコンパイル単位にこのフィールドをインライン化します。ここまでは順調ですね。public
と宣言されているため、コンパイラはこの値を他のコンパイル単位にインライン化することです。つまり、このフィールドを使用するotherクラス。結果は何ですか?
あなたがこれを持っていると想像してください:
class Foo {
public static final String VERSION = "1.0";
}
class Bar {
public static void main(String[] args) {
System.out.println("I am using version " + Foo.VERSION);
}
}
Bar
をコンパイルして実行すると、以下が得られます。
I am using version 1.0
ここで、Foo
を改善し、バージョンを「1.1」に変更します。 Foo
を再コンパイルした後、Bar
を実行すると、次の誤った出力が得られます。
I am using version 1.0
これは、VERSION
がfinal
として宣言されているために発生します。したがって、その実際の値は、最初のコンパイル実行時にBar
にすでにインライン化されています。そのため、final
(嘘をついた!)と宣言されたものを実際に変更した後、public static final ...
フィールドの例を適切に伝播させるには、それを使用してすべてのクラスを再コンパイルする必要があります。
私はこれを数回見ましたが、デバッグするのは本当に難しいです。
final
でmightがプログラムの以降のバージョンで変更される定数を意味する場合、より良い解決策は次のようになります。
class Foo {
private static String version = "1.0";
public static final String getVersion() {
return version;
}
}
JITコードジェネレーターは実行時にインライン化するため、これによるパフォーマンスの低下は無視できます。