15

在 Java 中,字符串是不可变的。如果我们有一个字符串并对其进行更改,我们将获得由同一变量引用的新字符串:

String str = "abc";
str += "def"; // now str refers to another piece in the heap containing "abcdef"
              // while "abc" is still somewhere in the heap until taken by GC

据说int 和 double 在 C# 中是不可变的。这是否意味着当我们拥有 int 并稍后对其进行更改时,我们将获得由同一变量“指向”的新 int?同样的东西,但有堆栈。

int i = 1;
i += 1; // same thing: in the stack there is value 2 to which variable
        // i is attached, and somewhere in the stack there is value 1

那是对的吗?如果不是, int 以什么方式不可变?

4

3 回答 3

21

To follow up on Marc's (perfectly acceptable) answer: Integer values are immutable but integer variables may vary. That's why they're called "variables".

Integer values are immutable: if you have the value that is the number 12, there's no way to make it odd, no way to paint it blue, and so on. If you try to make it odd by, say, adding one, then you end up with a different value, 13. Maybe you store that value in the variable that used to contain 12, but that doesn't change any property of 12. 12 stays exactly the same as it was before.

于 2012-12-23T07:09:14.527 回答
16

你没有改变(也不能改变)关于 int 的一些东西;您已经分配了一个的int 值(并丢弃了旧值)。因此它是不可变的。

考虑一个更复杂的结构:

var x = new FooStruct(123);
x.Value = 456; // mutate
x.SomeMethodThatChangedInternalState(); // mutate

x = new FooStruct(456); // **not** a mutate; this is a *reassignment*

但是,这里没有“指向”。结构直接在堆栈上(在这种情况下):不涉及引用。

于 2012-12-23T06:46:18.180 回答
2

虽然这听起来很明显,但我会添加几行帮助我理解的内容,以防有人有同样的困惑。

可变性有很多种,但一般来说,当人们说“不可变”时,他们的意思是类有不能改变的成员。

字符串可能将字符存储在数组中,该数组不可访问且无法通过方法更改,这就是字符串不可变的原因。对字符串的操作 + 总是返回一个新字符串。

int 可能将它的值存储在成员“Value”中,无论如何都无法访问,这就是为什么不能更改的原因。所有对 int 的操作都返回新的 int,并且这个值被复制到变量中,因为它是一个值类型。

于 2012-12-23T22:04:12.633 回答