9
public static final String Test = "ABC";
public static String Test = "ABC";

Javaの「finalstaticString」と「staticString」の違いを示してください。最後のものを変更することはできませんが、他の違いは何ですか?ありがとう。マルチスレッドや継承などのより複雑な状況では、何も変更されませんか?

4

14 に答える 14

9

以下の説明は Android doc から取得したものですが、この Java タグ付きの質問に役立つ場合があります。

クラスの先頭にある次の宣言を検討してください。

static int intVal = 42;
static String strVal = "Hello, world!";

コンパイラは、クラスが最初に使用されたときに実行される というクラス初期化メソッドを生成します。このメソッドは値 42 を intVal に格納し、クラスファイル文字列定数テーブルから strVal の参照を抽出します。これらの値が後で参照されるときは、フィールド ルックアップでアクセスされます。

「final」キーワードを使用して問題を改善できます。

static final int intVal = 42;
static final String strVal = "Hello, world!";

定数は dex ファイルの静的フィールド初期化子に入るため、このクラスにはメソッドが必要なくなりました。intVal を参照するコードは整数値 42 を直接使用し、strVal へのアクセスはフィールド ルックアップの代わりに比較的安価な「文字列定数」命令を使用します。

ノート:

この最適化は、任意の参照型ではなく、プリミティブ型と String 定数にのみ適用されます。それでも、可能な限り定数を static final として宣言することをお勧めします。

これがクリアされることを願っています。

詳細についてはUseFinalをご覧ください

于 2013-01-07T05:27:15.977 に答える
7

変数になると

  • final Static String-定数であり、クラス変数です
  • static String-定数ではなくクラス変数
于 2013-01-07T04:58:13.567 に答える
3

ここにもっとあります

static final String s1;
static String s2;

1行目はコンパイルせず、2行目はコンパイルします

プリミティブ型にはさらに多くのものがあります。

final int x = 1;

void x() {
    int y = x + 1;
}

バイトコード

ICONST_2
ISTORE 1

これはint y = 2、xが定数であるためです(静的ではありませんが)

変更した場合

int x = 1;

バイトコード

ALOAD 0
GETFIELD Test1.x : I
ICONST_1
IADD
ISTORE 1

JVMはxを読み取り、yを計算します

于 2013-01-07T05:02:06.727 に答える
1

ウィキによると

変数が参照である場合、これは、変数を再バインドして別のオブジェクトを参照できないことを意味します。ただし、元々変更可能であった場合、それが参照するオブジェクトは引き続き変更可能です。

ただし、Stringそもそも不変であるため、この場合の違いは関係なく、とにかく変更できない変数にすぎません。

于 2013-01-07T04:59:46.347 に答える
1

あなたはそれを自分で言いました:最後のものを割り当てることはできません。私の知る限り、final修飾子はそれ以外の動作を提供します。私が考えることができる唯一のことはTest、、、、publicおよびstaticfinalように、コンパイラはコード内のすべての出現箇所を自動的に置き換えTest、文字列リテラルに置き換えますが"ABC"、文字列はインターンされるため、コードに影響を与えることはありません。基本的に、finalは、文字列が別の参照に割り当てられるのを防ぎます。つまり、すべてです。

于 2013-01-07T05:01:28.630 に答える
1

クラスはfinalサブクラス化できません。sealedC#のクラスのようなものです。

メソッドはfinalオーバーライドできません。

フィールドは、定数のfinalように 1 回だけ初期化/代入できますが、コンパイル時に必ずしも認識されるとは限りません。

staticメンバーは、クラスのすべてのインスタンスで共有されます。

したがって、static final通常は二度と変更しないものですが、コンパイル時に必ずしもハードコードされるとは限りません。

于 2013-01-07T05:06:31.017 に答える
1

Java 変数を static final として宣言すると、コンパイルされた Java クラスのパフォーマンスが向上します。

これをチェックして

于 2013-01-07T05:09:03.500 に答える
0

最終変数はインスタンス変数であり、初期化後に値を変更することはできません。

しかし、静的変数はクラスに属しています。これは、すべてのインスタンス間で共有されます。したがって、インスタンスの静的変数の値を変更すると、すべてのインスタンスに反映されます。

于 2013-01-07T05:03:09.353 に答える
0

文字列の場合、他に違いはないと思います。

マルチスレッドの場合、提案されているのは、オブジェクトの状態の望ましくない状態変化のリスクがないように、オブジェクトを不変にすることを試みることです (不適切な同期または同期オーバーヘッドの回避による)。

finalキーワード (クラス、フィールド、メソッドなどのさまざまな場所) は、適切に使用すれば不変性を実現するのに役立ちますが、Strings はデフォルトで不変です。

継承の場合、最終メソッドをオーバーライドすることはできませんが、ここでもそうではありません。

于 2013-01-07T05:45:04.527 に答える
0

どうぞ:

1) final static String: final と言うと、それは定数であり、プログラム全体でその値を変更することはできません。これは変数ではありません。値を変更することはできません。Java では、final キーワードを使用して定数を宣言します。定数を宣言する間、単語を区切るためにすべての大文字の後にアンダースコアを付ける必要があります。例: MAX_INPUT_TIME、CONNECTION_POOL_SIZE、MAX_USER など。

2) static String: static はクラスのメンバー変数に使用できますが、ローカル変数には使用できません。静的変数は静的であり、クラスのインスタンスを作成しなくてもアクセスできます。object.<static_variable_name>したがって、またはのいずれかでそれらを使用できますClassName.<static_variable_name>。それらはアクセス可能で、クラスのすべてのインスタンスに対して同じ値を保持します。

例:

Class A {
  static int counter;  // it will be default to 0
}

このクラスを使用している間:

System.out.println(A.counter);  // output: 0
A.counter++;
System.out.println(A.counter);  // output: 1
// Declare an instance of class A
A o1 = new A();
o1.counter++;
System.out.println(o1.counter);  // output: 1
// Declare another instance of class A
A o2 = new A();
System.out.println(o1.counter);  // output: 1  
# You still get it one and not 0, if it was non-static you would get it as 0;

ここでは、たとえば、コンストラクター自体にカウンターのインクリメントを設定することで、作成されたオブジェクトの数を追跡する目的で静的変数を使用できます。

于 2013-01-07T05:32:18.017 に答える
0

final 静的文字列 - 定数であり、クラス変数です。アクセスできますが、どのクラスからも変更できません。静的文字列 - クラス変数であり、定数ではありません。任意のクラスからアクセスおよび変更できます

于 2013-01-07T06:01:32.363 に答える
0

最初のステートメントは、文字列定数を定義するためによく使用されると思います。また、定数変数名は「Test」ではなく「TEST」を推奨します。

public static final String TEST = "ABC";

2 番目のステートメントは、正当な理由でめったに使用されません。マルチスレッド コンテキストで同時実行の問題が発生する可能性があります。クラスにプライベート インスタンスの String フィールドを含めることができます。

private String test = "ABC";

お役に立てれば!

于 2013-01-07T06:03:46.030 に答える
0

以下のように final の参照を変更することはできません

public static final String Test1 = "ABC";
public static String Test2 = "ABC";
public static void testFinal()
{
    Test2 = Test1; //ok
    Test1 = Test2; //fail
}
于 2013-01-07T05:17:03.397 に答える
0

文字列は static と final の両方で宣言できます。両方のアクセス指定子を使用して string を宣言する利点については、以下で説明します。

利点には、final と static の両方の影響が含まれます。

  1. final として宣言された文字列は再割り当てできません。文字列は定数として機能します。

  2. static と宣言された文字列は、オブジェクトの助けを借りずに、またはクラス名を使用して呼び出すことができます..

  3. 静的変数はカプセル化を維持しません。static 変数を final として宣言すると、オブジェクトは値を変更できませんが、アクセスできます。

    public class Demo {
    
    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(Demo.str);// called with class name
    
    }
    }
    

文字列 str が final として宣言されているため、main() メソッドの最初のステートメントでエラーが発生します。

次のステートメントでは、文字列 str が final として宣言されているため、コンパイル エラーが発生します。

Demo d1 = new Demo();
d1.str =  "World";

リアルタイムの例

static final String true = "太陽は東から昇る";

于 2013-01-07T05:28:20.497 に答える