2010-03-19 1 views
3

Мне было интересно, можно ли в java, смоделировать pass by reference для массива? Да, я знаю, язык не поддерживает его, но я все равно могу это сделать. Скажем, например, я хочу создать метод, который изменяет порядок всех элементов в массиве. (Я знаю, что этот фрагмент кода - не лучший пример, так как для этого есть лучшие алгоритмы, но это хороший пример того, что я хочу сделать для более сложных проблем).Моделирование передачи по ссылке для ссылки на массив (например, ссылка на ссылку) в 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; 
} 

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

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

+1

Массив распространяется от java.lang.Object. Объекты в Java всегда передаются по ссылке. – Dan

+1

@ Dan: НЕТ! _Примечания к объектам в Java _passed значением_. И да, это означает что-то совершенно другое. – polygenelubricants

+1

Это объясняет это хорошо: http://stackoverflow.com/questions/40480/is-java-pass-by-reference/40523#40523 «Java всегда передается по значению. Трудно понять, что Java передает объекты в качестве ссылок, передаваемых по значению ». –

ответ

2

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

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

Вы можете, конечно:

  • Modify элементы упомянутого объекта массива (ала java.util.Arrays.sort)
  • Передайте ссылку на объект с устанавливаемым поля (например Throwable имеет setStackTrace)
  • return новая ссылка вместо этого (ala java.util.Arrays.copyOf)
+0

Возврат новой ссылки работает только в том случае, если у вас есть один массив, с которым вы работаете. – Gabe

+0

Вы можете вернуть массив массивов или инкапсулировать несколько массивов в качестве нового типа. – polygenelubricants

+0

Единственная проблема с этим в том, что программисту было бы неудобно помещать массив в другой массив, чтобы назвать его, но я думаю, что это сработает для других, более подходящих ситуаций. –

1

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

-1

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

+0

Да, я пробовал, и я знаю, что Java не создает целый массив. Скорее, он передает ссылку или указатель на массив. Однако на самом деле он не передается в ссылке, используемой, когда программист вызывает этот метод, а создает новый. Итак, когда вы скажете 'arr = tmpArr', arr начинает указывать на tmpArr, но когда он покидает этот метод, arr и все, что передавал программист для arr, не то же самое, что означает, что они получают старую, unrevised, array. –

1

Этот метод изменяет элементы массива на месте. Вызывающий видит изменения. (В 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; 
     } 
    } 
0

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

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

Смежные вопросы