60

次のJavaのコードは、のfinal配列を使用してStringおり、それについては疑問の余地はありません。

final public class Main {
  public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"};

  public static void main(String[] args) {
    for (int x = 0; x < CONSTANT_ARRAY.length; x++) {
      System.out.print(CONSTANT_ARRAY[x] + " ");
    }
  }
}

コンソールに次の出力が表示されます。

I can never change

次のコードも問題ありません。

final public class Main {
  public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"};

  public static void main(String[] args) {
    //CONSTANT_ARRAY={"I", "can", "never", "change"}; //Error - can not assign to final variable CONSTANT_ARRAY.
    for (int x = 0; x < CONSTANT_ARRAY.length; x++) {
      System.out.print(CONSTANT_ARRAY[x] + " ");
    }
  }
}

明らかに、コメントされた行は、finalタイプの宣言された配列を再割り当てしようとしているため、指定されたエラーを引き起こしますString


次のコードはどうですか。

final public class Main {
  public static final String[] CONSTANT_ARRAY = {"I", "can", "never", "change"};

  public static void main(String[] args) {
    CONSTANT_ARRAY[2] = "always";  //Compiles fine.
    for (int x = 0; x < CONSTANT_ARRAY.length; x++) {
      System.out.print(CONSTANT_ARRAY[x] + " ");
    }
  }
}

表示されるのは、型の配列のI can always change値をなんとか変更できることを意味します。のルールに違反することなく、この方法で配列全体を変更することはできますか?finalStringfinal

4

9 に答える 9

100

finalJavaでは変数に影響しますが、割り当てているオブジェクトとは何の関係もありません。

final String[] myArray = { "hi", "there" };
myArray = anotherArray; // Error, you can't do that. myArray is final
myArray[0] = "over";  // perfectly fine, final has nothing to do with it

コメントから追加するために編集:あなたがそれに割り当てているオブジェクトを言ったことに注意してください。Javaでは、配列はオブジェクトです。これと同じことが他のオブジェクトにも当てはまります。

final List<String> myList = new ArrayList<String>():
myList = anotherList; // error, you can't do that
myList.add("Hi there!"); // perfectly fine. 
于 2012-04-26T19:23:56.387 に答える
19

あなたは最終的な実装を誤って解釈しています。final配列オブジェクト参照に適用されます。つまり、一度開始されると、参照は変更できませんが、配列自体にデータを入力できます。「ルールに違反していません」あなたは、それに応じて機能している参照変更について1つのルールのみを指定しました。値も変更しないようにしたい場合は、不変リストを選択する必要があります。

List<String> items = Collections.unmodifiableList(Arrays.asList("I", "can", "never", "change"));
于 2012-04-26T19:34:12.707 に答える
11

配列参照を変更できないようにすることしかできません。要素を変更できないようにする場合は、何らかの変更不可能なコレクションを使用する必要があります。

于 2012-04-26T19:22:32.753 に答える
3

配列をfinalとして宣言すると、配列内の要素を変更できますが、この配列の参照を変更することはできません。

于 2012-04-26T19:24:46.353 に答える
3

finalは、プリミティブの不変性のみを保証します。また、変数が1回だけ割り当てられることを保証します。オブジェクトが変更可能である場合、finalとして定義されたイベントのコンテンツを変更できます。必要に応じて不変のコレクションをチェックできます。Collections.unmodizableList()など http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#unmodizableList(java.util.List

于 2012-04-26T19:26:11.690 に答える
2

配列オブジェクトへの参照はfinalです(たとえば、別のJava配列オブジェクト(String []のインスタンス)を同じfinal変数に関連付けようとする場合は変更できません...コンパイル時エラーが発生します)。

ただし、例のfinal配列オブジェクトのフィールドはfinalではないため、値を変更できます。...作成したJavaオブジェクトの間、CONSTANT_ARRAYは、初期値を受け取った後、JVMが停止するまでその値を「永久に」==持つことになります。:)それは「永遠に」同じ文字列配列インスタンスになります。

Javaの最終的な変数は大したことではありません。少し時間をかけて、トピック/アイデアを注意深く消化してください。:-)
このページについて瞑想するのが不確かな人には、たとえば https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12をお勧めします。 .4

それぞれの部分を引用させてください:

最終変数が割り当てられると、常に同じ値が含まれます。最終変数がオブジェクトへの参照を保持している場合、オブジェクトの状態はオブジェクトの操作によって変更される可能性がありますが、変数は常に同じオブジェクト。

配列はオブジェクトであるため、これは配列にも当てはまります。最終変数が配列への参照を保持している場合、配列のコンポーネントは配列の操作によって変更される可能性がありますが、変数は常に同じ配列を参照します。「」

于 2015-09-13T22:59:12.140 に答える
1

変数CONSTANT_ARRAYの値は変更できません。その変数には(への)配列が含まれています。ただし、配列の内容は変更される可能性があります。単純なスカラー型ではない任意の種類のfinal変数(オブジェクトなど)を宣言する場合にも同じことが起こります。

変数の名前の付け方に注意してください。:-) CONSTANT_ARRAYと呼んでも、配列の内容を変更できなくすることはありません。

ここに良い参考資料があります:finalの最後の言葉

于 2012-04-26T19:25:11.253 に答える
0

変数がfinalキーワードで宣言されている場合、その値は変更できません。基本的には定数です。これは、final変数を初期化する必要があることも意味します。最終変数が参照である場合、これは、変数を再バインドして別のオブジェクトを参照できないことを意味しますが、その参照変数が指すオブジェクトの内部状態を変更できます。つまり、最終配列から要素を追加または削除できます。最終コレクション。

于 2020-06-23T10:29:20.447 に答える
-2
    final int[] res;
    int[] res1;
    int[] res2 = new int[1];
    res2[0]=20;

    res1=res2;
    res1=res2;//no error
    System.out.println("res1:"+res1[0]);

    res = res2;//only once
   //res = res2;//error already initialised
    res2[0]=30;

    System.out.println("res:"+res[0]);     

出力::res1:20 res:30

于 2017-09-18T04:44:06.537 に答える