15

Javaで配列をfinalに宣言しても不変にならないのはなぜですか? 最終的なものを宣言することは、変更できないことを意味しませんか?

不変配列に関連する質問から、配列を final と宣言しても変更不可にならないことは明らかです。

以下が可能です。

final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;

私の質問は次のとおりです。ここで final を宣言する機能は何ですか?

4

6 に答える 6

32

finalそれによってマークされた参照についてのみです。Java には不変の配列などというものはありません。あなたが言う時

private final int[] xs = new int[20];

あなたは言うことを許されません

xs = new int[10];

後で。それがすべてですfinal。より一般的には、オブジェクトが不変であることを保証することは、多くの場合大変な作業であり、さまざまな微妙な点に満ちています。言語自体は、そのままではこの目的にあまり貢献しません。

于 2012-12-20T20:10:44.573 に答える
3

ここでは、プリミティブではなく、オブジェクト参照を作成しています。 final(配列も特殊な Java オブジェクトです。) 参照を作成するfinalとは、初期化された後は別のものを参照させることができないことを意味します。しかしもちろん、最終変数によって参照されるオブジェクトの状態を変更できます。

于 2012-12-20T20:10:52.200 に答える
1

配列の宣言

Javaでは、変数を宣言し、オブジェクト(配列など)を作成します。これらのアクションは独立しています。オブジェクトを作成せずに変数を宣言したり、変数を宣言せずにオブジェクトを作成したりできます。

不変性はオブジェクトのプロパティですが、finalは変数のプロパティです。オブジェクトは、いくつかの変数によって参照される場合があります。配列オブジェクトの不変性を管理する変数はどれですか?

int[] a = {1,2,3};
final int[] b = a;
a[0] = 10; // should this be legal?

これを許可すると、おそらく不変の値b[0]が変更されます。しかし、コンパイラはこれをどのように防ぐことができますか?非ファイナルをファイナルリファレンスに割り当てることを不可能にすることによって?では、どうすれば配列を初期化できますか?私はループでそうすることができませんでした...

そして:配列が不変であるとはどういう意味ですか?たとえば、次のようにコンパイルする必要がありますか?

final int[][] a = {{1,2}, {3,4}};
a[1][1] = 5;

constC ++は、間接参照のレベルごとに指定(または省略)できるようにすることで、これを解決します。Javaでは、finalは変数ごとに1回指定(または省略)できます。はい、 Javaがよりfinal単純constなC ++であるように、より単純です。シンプルにしましょう。

于 2012-12-23T19:09:26.660 に答える
0

これは、オブジェクトの新しいインスタンスが許可されないことを意味します。

于 2012-12-20T20:11:31.200 に答える