Java中的引用传递

Java中的引用传递,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中不存在按引用传递。在这种情况下

在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中不存在按引用传递。在这种情况下,最好的方法是什么。

您将术语“按引用传递”与“按值传递(对象的引用)”(这是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
    是对3
    int
    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 |-----/ +------------+ |