Java中的引用传递
在Java中如何通过引用传递数组?例如,我需要对数组A和B执行一些操作,并填充调用方应该可用的数组CJava中的引用传递,java,Java,在Java中如何通过引用传递数组?例如,我需要对数组A和B执行一些操作,并填充调用方应该可用的数组C public boolean Operate(int[] A, int[] B, int[] C) { //Write into the empty array C by manipulating values of A and B and it should be accessible to caller } 我认为与C#不同,Java中不存在按引用传递。在这种情况下
public boolean Operate(int[] A, int[] B, int[] C)
{
//Write into the empty array C by manipulating values of A and B and it should be accessible to caller
}
我认为与C#不同,Java中不存在按引用传递。在这种情况下,最好的方法是什么。您将术语“按引用传递”与“按值传递(对象的引用)”(这是Java和C#在没有out/ref的情况下所做的)。在上面的例子中,如果A、B或C的内容发生了更改,那么它们也会发生更改,因为在将它们传递给方法时没有创建/克隆/复制新对象。在C#中,“ref”和“out”如何使用“passbyreference”。请注意,当使用“通过引用传递”时,分配给变量会更改调用者传入的变量值(这在Java中是不可能的)
看
编辑:如果您真的希望采用这种方法,请记住调用约定并不规定对象的可变性。考虑以下事项:
void merge(int[] A, int[] B, int[][] C) {
int[] t = internalMerge(A, B);
C[0] = t;
}
int[][] icky = new int[1][0];
merge(..., ..., icky);
int[] r = icky[1];
但是,我只想更好地构造代码。几乎没有理由使用这种方法,它会带来更多的副作用和状态突变。如您所见,上面的代码已经引入了一个运行时错误。正如其他人所建议的,为什么不直接返回更合适的值呢?我假设您正在从该方法返回一个布尔值,以指示成功或失败
您可以从函数返回数组C,而不是返回布尔值。如果C为null,则表示函数失败。如果没有,则函数成功。我相信您对术语有点困惑。别担心。在java中,除原语外的所有内容都是通过引用传递的。对于您的数组,您可以在方法中填充它,并且更改将对调用方可见 在java中,总是通过引用传递数组。唯一未通过引用传递(但通过值传递)的对象是原语、
int、long、boolean、double、float等。其他所有对象都是通过引用传递的对象。因此,您的代码可以正常工作
编辑:我谦卑地承认我愚蠢的错误。在java中,您总是通过值进行传递。但是对象总是以引用作为值传递。正如您所说,在Java中,通过引用传递参数是不可能的
以下是解决您的问题的一些变通方法:
如果您已经知道数组C应该有多大,或者您只是希望该方法在不重新分配数组的情况下对数组进行更改。那你的方法就行了只是不要分配C
变量。
请参阅Philip Goh的答案-返回数组并检查函数的返回值(null
或not)以替换布尔值
如果您不知道数组C应该有多大,并且希望使用相同的签名,则将空的列表
传递给函数,然后将其转换为数组
您还可以创建一个ReferenceArgument
类,该类可以通过以下方式实现:
public final class ReferenceArgument<T> {
public T obj = null;
// You could also make the field private and use getter/setter methods.
}
public final class ReferenceArgument{
公共T obj=null;
//您还可以将字段设置为私有,并使用getter/setter方法。
}
不过,我建议不要这样做——但我相信它不能用于数组(不能与泛型很好地混合)——而且它会装箱基本类型,这有点笨拙
所有参数都按值传递。但是,在您的情况下,您有一个按值传递的引用(而不是数组中的数据)。这意味着引用已复制且无法更改,但它引用的数据可以更改。
e、 g
在Java中,数组是引用类型,而不是值类型。这意味着数组变量只存储对实际数组的引用
例如,考虑这个代码:
int[] numbers = new int[3];
在本例中,numbers
是对3int
s数组的引用。这可以如下所示:
Java Stack | Java Heap
|
| Array of ints:
+---------+ | +---+---+---+
| numbers |-------------->| 0 | 0 | 0 |
+---------+ | +---+---+---+
| 0 1 2
假设您使用数字
变量作为参数调用此方法:
int[] numbers = new int[3];
compure(numbers);
在这种情况下,numbers
引用按值传递给compute
。因此,someValues
是numbers
引用的副本(而不是numbers
引用的数组的副本)。因此,它看起来像这样:
public void compute(int[] someValues) {
someValues[2] = 78;
}
Java Stack | Java Heap
|
| Array of ints:
+---------+ | +---+---+---+
| numbers |-------------->| 0 | 0 | 0 |
+---------+ | --> +---+---+---+
| / 0 1 2
+------------+ | /
| someValues |-----/
+------------+ |
Java Stack | Java Heap
|
| Array of ints:
+---------+ | +---+---+----+
| numbers |-------------->| 0 | 0 | 78 |
+---------+ | --> +---+---+----+
| / 0 1 2
+------------+ | /
| someValues |-----/
+------------+ |
numbers[2]
将等于someValues[2]
,因为numbers
和someValues
引用相同的数组
唉,看来自从我开始写我的答案以来,这个问题也得到了类似的回答。希望ASCII图表值得保留 您将术语“按引用传递”与“按值传递(对象的引用)”混淆。在这里,我需要在处理具有值的A和B之后填充基于C的。C是一个空数组。调用约定和理解不同的约定在这里很重要。这就是为什么方法中的“C=f(A,B)”不能向外传播的原因。好的,我站出来更正。它将引用作为值传递。调用约定和理解不同的约定在这里很重要。这就是为什么方法内部的“C=f(A,B)”不会向外传播的原因。很好的演示。谢谢
Java Stack | Java Heap
|
| Array of ints:
+---------+ | +---+---+----+
| numbers |-------------->| 0 | 0 | 78 |
+---------+ | --> +---+---+----+
| / 0 1 2
+------------+ | /
| someValues |-----/
+------------+ |