为什么不声明一个数组最终使它在Java中不可变?不宣布最终意味着它无法改变吗?
从question related to immutable array可以清楚地看出,声明一个阵列最终版并不能使它不可更改。
以下是可能的。
final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;
我的问题是:那么在这里宣布决赛的功能是什么?
答案 0 :(得分:33)
final
仅关于由其标记的引用;在Java中没有不可变数组这样的东西。当你说
private final int[] xs = new int[20];
你不会被允许说
xs = new int[10];
稍后。这是{strong>全部 final
的内容。更一般地,确保对象是不可变的通常是艰苦的工作并且充满了一系列细微之处。语言本身没有为此提供太多开箱即用的结果。
答案 1 :(得分:8)
final
表示您无法更改引用 - 即您无法将另一个数组分配给该字段。
“不可变”表示您无法更改数组的内容 - final
对此无效。
如您的代码所示,您可以为数组的其中一个元素分配一个值,这不会更改对数组的引用
答案 2 :(得分:3)
您在这里制作对象引用 final
,而不是原语。 (数组也是特殊的Java对象。)
引用final
意味着一旦初始化你就无法引用它。但是,您当然可以更改最终变量引用的对象的状态。
答案 3 :(得分: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;
C ++通过允许为每个间接级别指定(或省略)const
来解决这个问题。在Java中,可以为每个变量指定(或省略)final。是的,final
更简单const
,就像Java是一个更简单的C ++。让我们保持简单,不管吗?
答案 4 :(得分:0)
这意味着不允许该对象的新实例。
答案 5 :(得分:0)
像所有人一样评论,声明它是最终的不会让你为你的变量分配另一个数组。阅读更多here
数组本身将保留与以前相同的属性。