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

Как увеличить значение класса Integer в java из другого метода

package myintergertest;

/**
 *
 * @author Engineering
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        //this one does not increment 
        Integer n = new Integer(0);
        System.out.println("n=" + n);
        Increment(n);
        System.out.println("n=" + n);
        Increment(n);
        System.out.println("n=" + n);
        Increment(n);
        System.out.println("n=" + n);
        Increment(n);

        //this one will increment
        MyIntegerObj myInt = new MyIntegerObj(1);
        Increment(myInt);
        System.out.println("myint = " + myInt.get());
        Increment(myInt);
        System.out.println("myint = " + myInt.get());
        Increment(myInt);
        System.out.println("myint = " + myInt.get());

    }

    public static void Increment(Integer n) {
        //NO.  this doesn't work because a new reference is being assigned
        //and references are passed by value in java
        n++;
    }

    public static void Increment(MyIntegerObj n) {
        //this works because we're still operating on the same object
        //no new reference was assigned to n here.
        n.plusplus();   //I didn't know how to implement a ++ operator...
    }
}

Результат для всех из них равен n = 0. Целое число n является объектом и поэтому передается по ссылке, поэтому почему инкремент не отражается обратно в методе вызывающего (main)? Я ожидал, что выход будет равен n = 0 n = 1 n = 2 и т.д.

UPDATE: Обратите внимание: я обновил приведенный выше пример кода. Если я правильно понимаю, Джон Скит ответил на вопрос, почему myInt будет увеличиваться, а почему нет. Это связано с тем, что n получает новую ссылку, назначенную в методе Increment. Но myInt НЕ получает новую ссылку, поскольку вызывает функцию-член.

Звучит ли так, что я правильно понимаю lol?

4b9b3361

Ответ 1

Нет, объекты не передаются по ссылке. Ссылки передаются по значению - там большая разница. Integer - неизменяемый тип, поэтому вы не можете изменить значение внутри метода.

Ваш n++; оператор эффективно

n = Integer.valueOf(n.intValue() + 1);

Итак, это присваивает переменную n в Increment другое значение, но поскольку Java имеет только пропускную способность, это не влияет на значение n в вызывающем методе.

EDIT: ответить на ваше обновление: это правильно. Предположительно, ваш тип "MyIntegerObj" изменен и изменяет свое внутреннее состояние при вызове plusplus(). О, и не беспокойтесь о том, как реализовать оператор - Java не поддерживает пользовательские операторы.

Ответ 2

Вы можете использовать AtomicInteger от java.util.concurrent.atomic. Он имеет метод "incrementAndGet", который подходит для вашей витрины.

Ответ 3

Вы ищете что-то похожее на ссылку С++ или параметр С#. Java (и многие другие языки) не поддерживает это.

Этот тип поведения обычно достигается путем изменения метода от void до (в этом случае) int: public static int increment(int n) { return ++n; }

Если метод уже возвращает что-то, вы можете создать новый класс, который имеет два поля (может даже быть общедоступным): исходное возвращаемое значение и новое значение n.

Кроме того, вы можете также обернуть целое число внутри общего класса Cell. Вам нужно только написать этот класс ячейки один раз:

public class Cell<T> {
  public Cell(T t) { value = t; }
  public void set(T t) { value = t; }
  public T get() { return value; }
}

Затем вы можете использовать его во всех ситуациях, когда вы хотите использовать метод для изменения примитива:

public static void increment(Cell<Integer> n) {
  n.set(n.get()++);
}

Cell<Integer> n = new Cell<Integer>(0);
increment(n);
increment(n);
increment(n);
System.out.println(n.get()); // Output: 3

Ответ 4

Как упоминал Джон Скит, все методы в Java передаются по значению, а не по ссылке. Поскольку ссылочные типы передаются по значению, то, что у вас внутри тела функции, является копией ссылки - эта копия и исходная ссылка указывают на одно и то же значение.

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

Но считайте, что вам действительно не нужна передача по ссылке, чтобы делать то, что вы хотите сделать. Например, вам не нужен метод для увеличения Integer - вы можете просто увеличить его в точке вашего кода, где его нужно увеличить.

Для более сложных типов, таких как установка некоторого свойства в объекте, объект, с которым вы работаете, скорее всего изменен; в этом случае копия справки работает просто отлично, так как автоматическое разыменование приведет вас к исходному объекту, чей сеттер вы вызываете.

Ответ 5

Вы не можете. Java строго передается по значению.

См. http://javadude.com/articles/passbyvalue.htm

Ваш выбор состоит в том, чтобы обернуть целое число в объект (или массив), передать это и обновить, вернуть значение или сделать целое число переменной класса/экземпляра.

Это лучше зависит от ситуации.

Ответ 6

Боковое примечание. По моему скромному мнению, запись n ++ в объекте Integer крайне вводит в заблуждение. Это зависит от функции Java, называемой "autoboxing", где она преобразует примитивы в соответствующие объекты бокса - например, int Integer или boolean to Boolean - автоматически и без предупреждения. Честно говоря, я считаю это плохой особенностью. Да, иногда это упрощает вашу жизнь, автоматически делая для вас удобное преобразование, но оно также может делать конверсии, которые вы не намеревались и не понимаете, происходят с непреднамеренными побочными эффектами.

Во всяком случае, есть два способа выполнить то, что вы, по-видимому, пытаетесь сделать:

One: добавляет ли функция increment новое целое число с обновленным значением. Например:

   public Integer increment(Integer n)
    {
      Integer nPlus=Integer.valueOf(n.intValue()+1);
    }

затем назовите его с помощью

Integer n=Integer.valueOf(0);
n=increment(n); // now n==1
n=increment(n); // now n==2

Etc.

Два: создайте свой собственный класс, похожий на Integer, но изменяемый. Как:

class MutableInteger
{
  int value;
  public MutableInteger(int n)
  {
    value=n;
  }
  public void increment()
  {
    ++value;
  }
  ... whatever other functions you need ...
}

Конечно, большой улов в этом состоит в том, что вы в значительной степени должны изобретать класс Integer.

Ответ 7

Как упоминалось в DerMike, вы можете достичь этого следующим образом:

public void doStuff() {
  AtomicInteger i = new AtomicInteger(0);
  increment(i);
  System.out.println(i);
 }

  public void increment(AtomicInteger i) {
    i.set(i.get() + 1);
 }

Ответ 8

Integer является объект значения, что означает, что значение не может быть изменено.

Обратите внимание, что n++ является эквивалентом n = n + 1. Вы просто меняете значение, на которое ссылается локальная переменная n, а не значение n.