Подтвердить что ты не робот

Как передать примитивный тип данных по ссылке?

Как передать примитивный тип по ссылке в java? Например, как мне передать int метод, который может быть изменен?

4b9b3361

Ответ 1

Невозможно передать примитив напрямую по ссылке на Java.

Обходной путь заключается в том, чтобы вместо этого передать ссылку на экземпляр класса-оболочки, который затем содержит примитив в качестве поля-члена. Такой класс обертки может быть предельно простым для себя:

public class IntRef { public int value; }

Но как насчет некоторых предварительно построенных классов-оболочек, поэтому нам не нужно писать самостоятельно? OK:

Apache commons-lang Mutable * classes:
Преимущества: Хорошая производительность для однопоточного использования. Полнота.
Недостатки: вводит стороннюю библиотечную зависимость. Нет встроенных элементов управления concurrency.
Репрезентативные классы: MutableBoolean, MutableByte, MutableDouble, MutableFloat, MutableInt, MutableLong, MutableObject, MutableShort.

java.util.concurrent.atomic Атомные * классы:
Преимущества: часть стандартного API Java (1.5+). Встроенные элементы управления concurrency.
Недостатки: малая производительность при использовании в однопоточной настройке. Отсутствует прямая поддержка некоторых типов данных, например. нет AtomicShort.
Репрезентативные классы: AtomicBoolean, AtomicInteger, AtomicLong и AtomicReference.
Примечание. Как показывает пользователь ColinD в своем ответе, AtomicReference может использоваться для аппроксимации некоторых из отсутствующих классов, например. AtomicShort.

массив примитивов длины 1
Ответ OscarRyz демонстрирует использование массива длиной 1 для "обертывания" примитивного значения.
Преимущества: Быстрая запись. Производительный. Не требуется сторонняя библиотека.
Недостатки: Немного грязные. Нет встроенных элементов управления concurrency. Результаты в коде, который не делает (явно) самодокумент: есть ли массив в сигнатуре метода, чтобы я мог передавать несколько значений? Или это здесь как подмостки для эмуляции перекрестных ссылок?

Также см.
Ответы на вопрос StackOverflow "Mutable boolean field в Java.

Мое мнение
В Java вы должны стремиться использовать вышеупомянутые подходы экономно или совсем не. В C обычно используется возвращаемое значение функции для передачи кода состояния (SUCCESS/FAILURE), в то время как фактический выход функции ретранслируется через один или несколько параметров out. В Java лучше использовать Исключения вместо кодов возврата. Это освобождает значения возвращаемого метода метода, которые будут использоваться для переноса фактического вывода метода - шаблон проектирования, который большинство программистов Java считают более естественным, чем out-parameters.

Ответ 2

Ничто в java не передается по ссылке. Все прошло по значению.

Изменить: Оба примитива и типы объектов передаются по значению. Вы никогда не сможете изменить переданное значение/ссылку и ожидать, что исходное значение/ссылка изменится. Пример:

String a;
int b;

doSomething(a, b);

...

public void doSomething(String myA, int myB) {
   // whatever I do to "myA" and "myB" here will never ever ever change
   // the "a" and "b"
}

Единственный способ обойти это препятствие, независимо от того, является ли оно примитивным или ссылкой, - это передать объект-контейнер или использовать возвращаемое значение.

С держателем:

private class MyStringHolder {
  String a;
  MyStringHolder(String a) {
    this.a = a;
  }
}

MyStringHolder holdA = new MyStringHolder("something");

public void doSomething(MyStringHolder holder) {
   // alter holder.a here and it changes.
}

С возвратным значением

int b = 42;
b = doSomething(b);

public int doSomething(int b) {
  return b + 1;
}

Ответ 3

Передайте AtomicInteger, AtomicBoolean и т.д. вместо. Для каждого примитивного типа нет ни одного, но при необходимости вы можете использовать, скажем, AtomicReference<Short>.

Заметьте: очень редко нужно делать что-то подобное на Java. Когда вы захотите это сделать, я бы рекомендовал переосмыслить то, что вы пытаетесь сделать, и посмотреть, не можете ли вы сделать это каким-либо другим способом (используя метод, который возвращает int, скажите... что именно самое лучшее вещь, которую нужно сделать, будет отличаться от ситуации к ситуации).

Ответ 4

Это невозможно в Java, в качестве альтернативы вы можете обернуть его в один массив элементов.

void demo() { 
    int [] a = { 0 };
    increment ( a ) 
}
void increment( int [] v ) { 
     v[0]++;
}

Но всегда есть лучшие варианты.

Ответ 6

Передайте объект, который имеет это значение в качестве поля.

Ответ 7

Это невозможно в Java

Ответ 8

Один из вариантов заключается в использовании таких классов, как java.lang.Integer, тогда вы не передаете примитив вообще.

С другой стороны, вы можете просто использовать код, например:

int a = 5;
a = func(a);

и func возвращает измененное значение.