Как передать примитивный тип по ссылке в java? Например, как мне передать int
метод, который может быть изменен?
Как передать примитивный тип данных по ссылке?
Ответ 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]++;
}
Но всегда есть лучшие варианты.
Ответ 5
Вы не можете. Но вы можете вернуть целое число, которое является измененным значением
int i = 0;
i = doSomething(i);
Если вы переходите более чем к одному, вы можете создать "Объект передачи данных" (класс специально содержит набор переменных, которые может быть передан классам).
Ответ 6
Передайте объект, который имеет это значение в качестве поля.
Ответ 7
Это невозможно в Java
Ответ 8
Один из вариантов заключается в использовании таких классов, как java.lang.Integer, тогда вы не передаете примитив вообще.
С другой стороны, вы можете просто использовать код, например:
int a = 5;
a = func(a);
и func возвращает измененное значение.