【问题标题】:Simulating pass by reference for an array reference (i.e. a reference to a reference) in Java在 Java 中模拟数组引用(即对引用的引用)的引用传递
【发布时间】:2011-01-29 07:21:34
【问题描述】:

我想知道,在 java 中,无论如何都可以模拟数组的引用传递吗?是的,我知道该语言不支持它,但无论如何我可以做到。比如说,我想创建一个方法来反转数组中所有元素的顺序。 (我知道这段代码 sn-p 不是最好的例子,因为有更好的算法可以做到这一点,但这是我想要为更复杂的问题做的事情的一个很好的例子)。

目前,我需要制作这样的课程:

public static void reverse(Object[] arr) {
    Object[] tmpArr = new Object[arr.length];
    count = arr.length - 1;
    for(Object i : arr)
        tmpArr[count--] = i;
    // I would like to do arr = tmpArr, but that will only make the shallow
    // reference tmpArr, I would like to actually change the pointer they passed in
    // Not just the values in the array, so I have to do this:
    for(Object i : tmpArr)
        arr[count++] = i;
    return;
}

是的,我知道我可以只交换值直到我到达中间,这样会更有效率,但对于其他更复杂的目的,我是否可以操纵实际的指针?

再次感谢您。

【问题讨论】:

  • 一个数组从 java.lang.Object 扩展而来。 Java 中的对象总是通过引用传递。
  • @Dan:不! 对 Java 中对象的引用按值传递。是的,这意味着完全不同的东西。
  • 这很好地解释了它:stackoverflow.com/questions/40480/is-java-pass-by-reference/…“Java 总是按值传递。很难理解 Java 将对象作为按值传递的引用传递。”
  • @polygenelubricants:如何区分通过引用传递的值和通过值传递的引用?
  • 在 Java 中,没有必要区分这两种机制,因为其中一种机制是不可能的;一切都是按值传递的。如果您想真正理解每个定义的真正含义,我建议您阅读一些内容。

标签: java arrays pass-by-reference


【解决方案1】:

无论如何我可以操纵实际的指针吗?

Java 不通过引用传递,所以不能直接操作原始指针。正如您所发现的,Java 通过值传递所有内容。 您不能传递对数组对象的引用,并期望一个方法修改原始引用以指向另一个数组对象

当然可以:

  • 修改引用数组对象的元素(ala java.util.Arrays.sort
  • 传递对具有可设置字段的对象的引用(例如,Throwable 具有 setStackTrace
  • return 改为新的参考 (ala java.util.Arrays.copyOf)

【讨论】:

  • 仅当您正在使用单个数组时,返回新引用才有效。
  • 可以返回一个数组数组,也可以将多个数组封装成一个新类型。
  • 唯一的问题是程序员不得不将数组放在另一个数组中调用它会很尴尬,但我想这适用于其他更合适的情况。
【解决方案2】:

好吧,您可以显式传递一个包含引用的对象。 java.util.concurrent.atomic.AtomicReference 开箱即用,尽管它确实带有您可能不想要的易变语义。有些人使用单元素数组从匿名内部类返回值(尽管这对我来说似乎不是一个好主意)。

【讨论】:

    【解决方案3】:

    此方法将 Array 的元素反转到位。调用者看到更改。 (在 Java 中,一切都是按值传递的,包括对象引用。)

       public static void reverse(Object[] arr) {
           for ( int i = 0, j = arr.length - 1;   i < j;   i++, j-- ) {
               Object temp = arr[i];
               arr[i] = arr[j];
               arr[j] = temp;
           }
       }
    

    【讨论】:

      【解决方案4】:

      在 Java 中,对象引用是按值传递的。

      所以如果你在寻找类似的东西

      function referenceCheck()
      {
          int[] array = new int[]{10, 20, 30};
          reassignArray(&array);
          //Now array should contain 1,2,3,4,5
      }
      
      function reassignArray(int **array)
      {
          int *array = new int[] { 1, 2, 3, 4, 5};
      }
      

      那么它在 Java 中是不可能通过任何直接方式实现的。

      如果我们只需要更改存储在数组中的值,那么我们可以这样做,因为对象引用是按值传递的。

      【讨论】:

        【解决方案5】:

        您想将引用传递给数组引用。在这种情况下,您只需要创建一个类来保存引用并将引用传递给该类,或者只传递所传递类型的 1 元素数组。然后,您将传递一个包含数组的对象或一个数组,其唯一元素包含您要操作的数组。

        【讨论】:

        • 是的,我试过了,我知道java不会创建一个完整的数组。相反,它传递一个指向数组的引用或指针。但是,它实际上并没有传入程序员调用该方法时使用的引用,而是创建一个新的引用。因此,当您说“arr = tmpArr”时,arr 确实开始指向 tmpArr,但是当它离开该方法时,arr 以及程序员为 arr 传递的任何内容都不相同,这意味着它们会变旧,未修改,数组。
        猜你喜欢
        • 2012-02-20
        • 1970-01-01
        • 2016-06-06
        • 2014-04-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-29
        相关资源
        最近更新 更多