为什么不声明一个数组 final 使其在 Java 中不可变?声明最终的东西不意味着它不能改变吗?
从与不可变数组相关的问题中,很明显声明一个数组 final 并不能使其不可更改。
以下是可能的。
final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;
我的问题是:那么在这里声明 final 的功能是什么?
为什么不声明一个数组 final 使其在 Java 中不可变?声明最终的东西不意味着它不能改变吗?
从与不可变数组相关的问题中,很明显声明一个数组 final 并不能使其不可更改。
以下是可能的。
final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;
我的问题是:那么在这里声明 final 的功能是什么?
final
仅与它所标记的参考有关;Java中没有不可变数组这样的东西。当你说
private final int[] xs = new int[20];
你不能说
xs = new int[10];
稍后的。这就是全部内容final
。更一般地说,确保一个对象是不可变的通常是一项艰巨的工作,并且充满了一系列微妙之处。语言本身并没有为此提供太多开箱即用的功能。
final
意味着您不能更改引用- 即您不能将另一个数组分配给该字段。
“不可变”意味着您无法更改数组的内容final
-对此没有影响。
如您的代码所示,您可以为数组的一个元素分配一个值,这不会更改对数组的引用
在这里,您正在创建对象引用 final
,而不是原始对象。(数组也是特殊的 Java 对象。)创建一个引用final
意味着一旦它被初始化就不能让它引用其他东西。当然,您可以更改由 final 变量引用的对象的状态。
声明一个数组
在 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++。让我们保持简单,好吗?
这意味着不允许对象的新实例。
就像每个人评论的那样,将其声明为 final 不会让您将另一个数组分配给您的变量。在这里阅读更多
数组本身将保留与以前相同的属性。