Why does creating an array from primitives copy them?

出于完全相同的原因:

int a = 5;
int b = a;

…将a的值复制到b中,而不在a和b之间创建任何类型的链接:复制值,而不是对变量的某种引用.

你的评论:

But when we operate on reference types, the reference copies, doesn’t it?

是的,确实如此,就像在int场景中复制的那样.

无论a和b是基本类型变量还是引用类型变量,b = a(或你的数组初始值设定项)的工作方式都完全相同:a中的值被复制到b,然后a和b之间没有正在进行的链接.

唯一的区别是,当你处理引用类型时,变量中的值不是实际的东西,它是对实际事物的引用.因此,将该引用从一个变量复制到另一个变量只会使得这两个变量引用相同的东西,就像上面的代码使a和b都具有值5一样.

考虑一下:让我们创建一个列表:

List a = new ArrayList();

这给了我们这样的记忆:

+----------+
a(55465)----->| the list |
+----------+

变量a包含一个值,该值是对象的引用.我已将上面的值描述为55465,但我们实际上从未在Java代码中看到原始值(并且随着垃圾收集的完成而改变).它只是一个值,就像任何其他值一样,它告诉JVM在内存中找到对象的位置.你可以把它想象成一个包含内存地址的long(这不是它真正的内容,但它在概念上有效).

现在我们这样做:

List b = a;

现在我们在内存中有这样的东西:

a(55465)--+
| +----------+
+--->| the list |
| +----------+
b(55465)--+

a和b都包含引用列表的值.

你可以看到它是如何完全像:

int a = 5

给我们

a(5)

然后

int b = a;

给我们

a(5)

b(5)

值在变量之间复制,传递给函数等.与引用类型的唯一区别在于该值的用途,解释方式.

If so, I would say that java is pass by value in the sense of copying values of primitives and the references of reference types. Right?

“按值传递”和“按引用传递”在计算中具有特定含义:它是关于变量的引用,而不是对象.这是传递参考的样子:

// 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

传递引用与对象引用无关.他们唯一的共同点是“参考”这个词. Java是一种纯粹的传值语言.