Как передать значение по ссылке в java

#java #function #parameter-passing

#java #функция #передача параметров

Вопрос:

 public class JavaApplication6 {

    public static void a(int b)
    {
        b  ;
    }
  

Я вызываю функцию a и передаю переменную b с намерением увеличить ее, как ссылку на C ( amp;b ) . Будет ли это работать? Если нет, то почему?

     public static void main(String[] args) {

        int b=0;
        a(b);
        System.out.println(b);
    }

}
  

Комментарии:

1. Вы не можете этого сделать.

2. но почему я могу сделать это на c , просто передав переменную в функцию по ссылке, есть ли какой-либо способ сделать это, кроме глобального объявления

3. В Java это передается по значению, и, следовательно, вы не можете изменить значение b . В то время как на таких языках программирования, как C, C , вы можете передавать указатель, а с помощью указателя вы можете увеличивать значение.

4. Как правило, это плохая идея и приводит к сложному нечитаемому коду. Какую проблему вы пытаетесь решить?

5. Вы не можете «изначально» сделать это, но вы могли бы определить свой собственный MyInt класс с одной ссылкой на переменную-член int b , которую вы можете изменить

Ответ №1:

Хотя вы не можете действительно выполнить это с int помощью (примитивного типа для integer), вы можете выполнить что-то очень похожее с помощью AtomicInteger . Просто вызовите метод getAndIncrement для экземпляра класса. Что-то вроде этого:

 public static void a(AtomicInteger b) {
    b.getAndIncrement();
}
  

(Обратите внимание, что вы также не можете сделать это с помощью java.lang.Целое число, потому что java.lang.Integer — это неизменяемый класс.)

Комментарии:

1. Вы можете сделать это для любого типа данных с AtomicReference помощью . Тем не менее, это далеко от идиоматической Java и обычно не рекомендуется.

2. Хотя это решает задачу, использование AtomicInteger только для использования его изменяемого свойства, вероятно, не лучшая идея из-за неблокирующих накладных расходов на синхронизацию.

Ответ №2:

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

 b = a(b);
  

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

 public static class MutableInteger {
    public int value;

    public MutableInteger(int value) {
        this.value = value;
    }
}

public static void main(String[] args) {
    MutableInteger b = new MutableInteger(2);
    increment(b);
    System.out.println(b.value);
}

public static void increment(MutableInteger mutableInteger) {
    mutableInteger.value  ;
}
  

При запуске этого кода на консоль будет выведено следующее:

 3
  

В конце концов, использование приведенного выше требует веских аргументов со стороны программиста.

Ответ №3:

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

 class Holder {
  int b;
}
  

Теперь вы можете изменить значение, выполнив :

 public static void a(Holder h) {
  h.b  ;
}
  

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

Комментарии:

1. h.b = h.b ; серьезно?

2. Нет; это ничего не делает. Оператор постфиксного инкремента возвращает исходное значение.

3. Ups. Исправлено.

4. Но почему не просто h.b ; ?

Ответ №4:

Вы не можете передать значение по ссылке в Java. Если методу передается примитив, JVM передает его по значению. Если это объект, который отправляется в метод, JVM создает копию его ссылки. Поскольку это «копия», модификация не изменит исходный объект. Но все же есть обходной путь, например, использование AtomicInteger, предложенного в предыдущих сообщениях.