在该计划中
public static void main(String[] args){
int x = 1;
int y = 2;
int[] z = new int[]{x, y};
z[0] = 3;
System.out.println(x); //prints 1
}
Run Code Online (Sandbox Code Playgroud)
我预计会打印出3张.但是1是.为什么?我认为Java只复制引用,即当我们将refrence传递给方法时,该方法将使用对同一对象的另一个引用.它就像C++指针和原始类型.
所以我试着咨询JLS 10.6并没有找到任何有用的东西.也许我对Java中的原始类型有一些误解.你能澄清一下吗?
T.J*_*der 11
为什么从基元创建数组会复制它们?
出于完全相同的原因:
int a = 5;
int b = a;
Run Code Online (Sandbox Code Playgroud)
...复制ainto 的值b,而不在a和之间创建任何类型的链接b:复制值,而不是对变量的某种引用.
你的评论:
但是当我们操作引用类型时,引用副本,不是吗?
是的,确实如此,就像你的int场景中复制的数字一样.
b = a(或数组初始化)的工作原理完全相同的方式不管是否a和b是原始类型的变量或引用类型的变量:该值在a被复制到b,然后之间不存在正在进行的链路a和b.
唯一的区别是,当你处理引用类型时,变量中的值不是实际的东西,它是对实际事物的引用.因此,将该引用从一个变量复制到另一个变量只会使得这两个变量引用相同的东西,就像上面的代码所做的那样a,b两者都具有值5.
考虑一下:让我们创建一个列表:
List<String> a = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)
这给了我们这样的记忆:
+----------+
a(55465)----->| the list |
+----------+
该变量a包含一个值,该值是对象的引用.我已将上面的值描述为55465,但我们实际上从未在Java代码中看到原始值(并且随着垃圾收集的完成而改变).它只是一个值,就像任何其他值一样,它告诉JVM在内存中找到对象的位置.你可以把它想象成一个long包含一个内存地址(这不是它真正的内容,但它在概念上有效).
现在我们这样做:
List<String> b = a;
Run Code Online (Sandbox Code Playgroud)
现在我们在内存中有这样的东西:
a(55465)--+
| +----------+
+--->| the list |
| +----------+
b(55465)--+
双方a并b包含一个值,它指的是列表.
你可以看到它是如何完全像:
int a = 5
Run Code Online (Sandbox Code Playgroud)
给我们
a(5)
然后
int b = a;
Run Code Online (Sandbox Code Playgroud)
给我们
a(5) b(5)
值在变量之间复制,传递给函数等.与引用类型的唯一区别在于该值的用途,解释方式.
如果是这样,我会说java在复制基元值和引用类型引用的意义上是通过值传递的.对?
"按值传递"和"按引用传递"在计算中具有特定含义:它是关于变量的引用,而不是对象.这是传递参考的样子:
// NOT JAVA; Java doesn't have this
void foo(int &a) { // Fake pass-by-reference thing
a = 3;
}
int a = 5;
foo(&a); // Fake pass-by-reference operator
System.out.println(a); // 3
Run Code Online (Sandbox Code Playgroud)
传递引用与对象引用无关.他们唯一的共同点是"参考"这个词.Java是一种纯粹的传值语言.