i
:int i = 10;
然后我分配一个新值:
i = 11;
这会分配新的内存位置吗?还是只是替换原来的值?
这是否意味着原始数据类型是不可变的?
me
从指向我改为指向其他人一样:它实际上并没有改变我,只是改变了me
。StringBuilder sb = new StringBuilder("foo");
sb.append("bar"); // mutate the object identified by sb
sb = new StringBuilder(); // change sb to identify a different object
sb = null; // change sb not to identify any object at all
通常情况下,这两者都会被描述为“改变sb
”,因为人们会使用“sb
”来指代变量(其中包含一个引用),以及它所指代的对象(当它指代一个对象时)。只要你在重要时刻记得这个区别,这种松散的用法是可以接受的。
Immutable
意味着每次对象的值发生更改时,都会在堆栈中为其创建一个新的引用。只有包装类才是不可变的,原始类型无法谈及不可变性。
在Java中,使用的是按值传递的方式(copy_by_value)而非按引用传递。
无论传递的是基本类型还是引用变量,都传递了变量位中位表示值的拷贝。因此,对于基本类型变量,传递的是代表值的位的拷贝,如果传递的是对象引用变量,则传递的是代表对象引用的位的拷贝。
例如,如果传递一个值为3的int变量,则传递代表3的位的拷贝。
一旦声明了一个基本类型,它的基本类型永远不能改变
,尽管它的值可以改变。
让我们更进一步,在其中添加另一个变量j。
int i = 10;
int j = i;
i = 11
对于对象来说,值(或引用)本身就是地址(或堆地址),因此如果更改它,其他人也会反映出来。例如,在对象中:
Person p1 = new Person();
Person p2 = p1;
所以,无论是p1还是p2进行更改,都将对两者进行更改。无论是Java、Python还是Javascript,都是一样的。对于原始类型,它是实际值,但对于对象而言,则是实际对象的地址——这就是诀窍。
int i = 10; // assigned i the literal value of 10
5 = i; // reassign the value of 5 to equal 10
System.out.println(5); // prints 10
当然,这是不正确的。
整数值,例如5、10和11已经存储在内存中。当你将变量设置为其中之一时:它会改变内存槽中i的值。
你可以通过以下代码的字节码看到这一点:
public void test(){
int i = 10;
i = 11;
i = 10;
}
字节码:
// access flags 0x1
public test()V
L0
LINENUMBER 26 L0
BIPUSH 10 // retrieve literal value 10
ISTORE 1 // store it in value at stack 1: i
L1
LINENUMBER 27 L1
BIPUSH 11 // same, but for literal value 11
ISTORE 1
L2
LINENUMBER 28 L2
BIPUSH 10 // repeat of first set. Still references the same literal 10.
ISTORE 1
L3
LINENUMBER 29 L3
RETURN
L4
LOCALVARIABLE this LTest; L0 L4 0
LOCALVARIABLE i I L1 L4 1
MAXSTACK = 1
MAXLOCALS = 2
正如您在字节码中所看到的(希望如此),它引用了文字值(例如:10),然后将其存储在变量i的槽中。当您更改i
的值时,实际上只是更改存储在该槽中的值。这些值本身并没有改变,只是它们的位置发生了变化。
是的,它们是不可变的。它们完全无法更改。
这里有一个很好的解释。虽然是针对Go语言的,但在Java或任何其他C系列语言中都是一样的。
原始字面量和final
原始变量是不可变的。非final
原始变量是可变的。
任何原始变量的标识都是该变量的名称,显然这种标识是不可改变的。
Integer
(以及其他原始包装类)是不可变的。 - Luiggi MendozaString str = "test"; str = "newStr";
。回答OP的问题,实际上它们是不可变的。如果考虑i++
,那么实际上是:i = i + 1
。你可以看到它获取i
的值,加一并将i
重新赋值为这个新值。 - user1181445