我有一个关于在java中传递值和通过引用传递的问题。
我有一个“Graph”类,我编写它来显示一个长数组的双精度图形,(简化)构造函数看起来像这样。
private double[] Values;
public Graph(double[] values) {
Values = values;
}
阵列可能很长并占用合理的内存量。
基本上我的问题是这样的:如果我调用构造函数来创建一个新图形,那么数组“Values”是传递给它的数组的副本,还是它会被引用?
在我看来,Primitives是“按值传递”而对象是“通过引用传递”,这应该意味着数组将是一个副本。虽然我知道这个定义在技术上并不正确。
如果我是正确的,并且数组是副本,那么减少此类使用的内存量并从另一个类引用该数组的最佳方法是什么? 抽象的GetValues()方法是否是实现此目的的好方法?
提前致谢,
克里斯。
答案 0 :(得分:6)
虽然double
是基本类型,double[]
是一个Object类型(数组),所以,不,整个数组都不会传递给构造函数,而是将数组作为“参考价值“。您将无法替换构造函数中的数组,但如果需要,您可以替换数组中的各个值。
答案 1 :(得分:4)
Java是按值传递,期间。
请参阅JLS,4.12.3 Kinds of Variables:
方法参数(第8.4.1节)传递给方法的名称参数值。对于方法声明中声明的每个参数,每次调用该方法时都会创建一个新的参数变量(第15.12节)。使用方法调用中的相应参数值初始化新变量。当方法体的执行完成时,方法参数有效地停止存在。
编辑:澄清我的答案:Java的类型分为两类:基元和引用类型。无论何时调用方法(或构造函数),都会复制参数(因为Java是按值传递)。原语被完全复制,对于引用类型,引用被复制。 Java永远不会自动深层复制任何东西,因为数组是引用类型,只会复制对数组的引用。
答案 2 :(得分:2)
它将是values
的参考。 Java是按值传递,但是通过值传递的是对数组的引用,因为数组是一个对象。
仅在几天前参见this answer。
答案 3 :(得分:0)
这将是一个参考。参数values
传递“按值引用”,引用附加到Values
。
因此 - Graph.Value
的所有内容也会反映到values
,反之亦然。
答案 4 :(得分:0)
数组是引用类型,传递副本仅适用于基本类型,而数组则不适用。其他参考类型包括类和接口。
答案 5 :(得分:0)
// Points:
// 1) primitive variables store values
// 2) object variables store addresses(location in the heap)
// 3) array being an object itself, the variables store addresses again (location in the heap)
// With primitives, the bit by bit copy of the parameters, results in the
// value being copied. Hence any changes to the variable does not propagate
// outside
void changePrimitive(int a) {
a = 5;
}
// With objects, the bit by bit copy of the parameters, results in the address
// begin copied. Hence any changes using that variable affects the same object
// and is propogated outside.
class obj {
int val;
}
void changeObject(obj a) {
a.val = 10;
}
// Array is itself an object which can hold primitives or objects internally.
// A bit by bit copy of the parameters, results in the array's address
// being copied. Hence any changes to the array contents reflects in all
// the locations having that array.
void changeArray(int arr[]) {
arr[0] = 9;
arr[1] = 8;
}
// NOTE: when object/array variable is assigned a new value, the original
// object/array is never affected. The variable would just point to the
// new object/array memory location.
void assignObj(obj a) {
a = new obj();
a.val = 10;
}