Как передать примитивный тип по ссылке в java? Например, как мне сделать int
переданным методу, который может быть изменен?Как передать примитивный тип данных по ссылке?
ответ
Невозможно передать примитив непосредственно по ссылке в Java.
Обходным путем является передача ссылки на экземпляр класса-оболочки, который затем содержит примитив в качестве поля-члена. Такой класс-оболочка может быть очень простым, чтобы написать для себя:
public class IntRef { public int value; }
Но как о некоторых заранее построенных классов-оболочек, поэтому мы не должны писать свои собственные?OK:
В Apache commons-lang Mutable * Классы:
Преимущество: Хорошая производительность для однотридового использования. Полнота.
Недостатки: Представляет зависимость от сторонней библиотеки. Нет встроенных средств параллелизма.
Представительные классы: MutableBoolean, MutableByte, MutableDouble, MutableFloat, MutableInt, MutableLong, MutableObject, MutableShort.
В java.util.concurrent.atomic Атомные * Классы:
Преимущества: Часть стандартной Java (1.5+) API. Встроенные средства управления параллелизмом.
Недостатки: Небольшое ударное воздействие при использовании в однопоточной настройке. Отсутствует прямая поддержка некоторых типов данных, например. нет AtomicShort.
Представительные классы: AtomicBoolean, AtomicInteger, AtomicLong и AtomicReference.
Примечание: Как пользователь ColinD shows in his answer, AtomicReference может использоваться для аппроксимации некоторых из отсутствующих классов, например. AtomicShort.
Длина 1 примитив массив
OscarRyz's answer демонстрирует использование массива длина от 1 до «обернуть» примитивное значение.
Преимущества: Быстро писать. Производительный. Не требуется сторонняя библиотека.
Недостатки: Немного грязные. Нет встроенных средств параллелизма. Результаты в коде, который не делает (явно) самодокумент: есть ли массив в сигнатуре метода, чтобы я мог передавать несколько значений? Или это здесь как строительные леса для перекрестной ссылки?
Также см
Ответы на StackOverflow вопрос "Mutable boolean field in Java".
Мое мнение
В Java, вы должны стремиться использовать вышеуказанные подходы экономно или нет вообще. В C обычно используется возвращаемое значение функции для ретрансляции кода состояния (SUCCESS/FAILURE), в то время как фактический выход функции ретранслируется через один или несколько параметров out. В Java лучше использовать Исключения вместо кодов возврата. Это освобождает значения возвращаемого метода метода, которые будут использоваться для переноса фактического вывода метода - шаблон проектирования, который большинство программистов Java считают более естественным, чем параметры out.
Это невозможно в Java
Ничего в 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;
}
технически правильно, но не очень полезно – 2010-11-30 23:34:29
Хорошо, я уточню. – 2010-11-30 23:35:14
«Правильно» является логическим условием и не допускает модификаторов степени или вида. – tchrist 2010-12-01 05:01:18
Pass объект, который имеет это значение в качестве поля.
Один из вариантов - использовать классы, такие как java.lang.Integer, то вы не передаете примитив вообще.
С другой стороны, вы можете просто использовать такой код:
int a = 5;
a = func(a);
и FUNC возвращает измененное значение.
Вы не можете. Но вы можете вернуть целое число, которое является измененным значением
int i = 0;
i = doSomething(i);
Если вы передаете более чем в одном вы можете создать Data Transfer Object (класс специально, чтобы содержать набор переменных, которые могут быть переданы на классы) ,
Передача AtomicInteger
, AtomicBoolean
и т. Д. Вместо этого. Для каждого примитивного типа нет ни одного, но вы можете использовать, скажем, и AtomicReference<Short>
, если это необходимо.
Обратите внимание: в Java очень редко нужно делать что-то подобное на Java. Когда вы захотите это сделать, я бы рекомендовал переосмыслить то, что вы пытаетесь сделать, и посмотреть, не можете ли вы сделать это другим способом (используя метод, который возвращает int
, скажите ... что именно самое лучшее для do будет варьироваться от ситуации к ситуации).
Это невозможно в Java, в качестве альтернативы вы можете обернуть его в один массив элементов.
void demo() {
int [] a = { 0 };
increment (a)
}
void increment(int [] v) {
v[0]++;
}
Но всегда есть лучшие варианты.
Я думаю, что это также относится к `Integer` – 2015-12-29 05:14:20