2010-11-30 4 views

ответ

67

Невозможно передать примитив непосредственно по ссылке в 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.

13

Ничего в 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; 
} 
+6

технически правильно, но не очень полезно – 2010-11-30 23:34:29

+0

Хорошо, я уточню. – 2010-11-30 23:35:14

+0

«Правильно» является логическим условием и не допускает модификаторов степени или вида. – tchrist 2010-12-01 05:01:18

2

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

-2

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

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

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

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

3

Вы не можете. Но вы можете вернуть целое число, которое является измененным значением

int i = 0; 
i = doSomething(i); 

Если вы передаете более чем в одном вы можете создать Data Transfer Object (класс специально, чтобы содержать набор переменных, которые могут быть переданы на классы) ,

13

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

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

10

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

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

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