Имитация передачи по ссылке для ссылки на массив (т.е. ссылки на ссылку) в Java - PullRequest
3 голосов
/ 19 марта 2010

Мне было интересно, в Java, можно ли в любом случае имитировать передачу по ссылке для массива? Да, я знаю, что язык не поддерживает это, но в любом случае я могу это сделать. Скажем, например, я хочу создать метод, который меняет порядок всех элементов в массиве. (Я знаю, что этот фрагмент кода не лучший пример, так как для этого есть лучшие алгоритмы, но это хороший пример того, что я хочу сделать для более сложных задач).

В настоящее время мне нужно создать такой класс:

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;
}

Да, я знаю, что могу просто поменять значения, пока не доберусь до середины, и это будет намного эффективнее, но для других, более сложных целей, в любом случае, я могу манипулировать фактическим указателем?

Еще раз спасибо.

Ответы [ 5 ]

2 голосов
/ 19 марта 2010

В любом случае, я могу манипулировать фактическим указателем?

Java не передается по ссылке, поэтому вы не можете напрямую манипулировать исходным указателем. Как вы узнали, Java передает все по значению. Нельзя передать ссылку на объект массива и ожидать, что метод изменит исходную ссылку для указания на другой объект массива .

Можно, конечно:

  • Изменить элементы упомянутого объекта массива (ala java.util.Arrays.sort)
  • Передать ссылку на объект с настраиваемым полем (например, Throwable имеет setStackTrace)
  • return новая ссылка вместо (ala java.util.Arrays.copyOf)
1 голос
/ 19 марта 2010

Этот метод переворачивает элементы массива на месте. Звонящий видит изменения. (В 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;
       }
   }
1 голос
/ 19 марта 2010

Ну, вы можете явно передать объект, который содержит ссылку. java.util.concurrent.atomic.AtomicReference готово из коробки, хотя и поставляется с изменчивой семантикой, которую вы, вероятно, не хотите. Некоторые люди используют одноэлементные массивы для возврата значений из анонимных внутренних классов (хотя это не кажется мне хорошей идеей).

0 голосов
/ 19 марта 2010

В объекте 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 любым прямым способом.

Если нам нужно изменить только значения, хранящиеся в массиве, мы можем это сделать, поскольку ссылка на объект передается по значению.

0 голосов
/ 19 марта 2010

Вы хотите передать ссылку на ссылку на массив. В этом случае вам просто нужно либо создать класс для хранения ссылки и передать ссылку на этот класс, либо просто передать массив из 1 элемента передаваемого типа. Тогда вы будете передавать либо объект, содержащий массив, либо массив, единственный элемент которого содержит массив, с которым вы хотите работать.

...