Как я могу передать Целочисленный класс правильно ссылкой?

Сохраните файл с расширением «.html». Например, «index.html». И тогда вы можете прямо на файл и выберите «открыть с» и выберите нужный браузер. Или же вы можете сначала открыть свой браузер. Затем перейдите в меню Файл -> Открыть -> Выбрать index.html

.
55
задан Community 23 May 2017 в 01:33
поделиться

7 ответов

Есть две проблемы:

  1. Целое число передается по значению, а не по ссылке. Изменение ссылки внутри метода не будет отражено в переданной ссылке в вызывающем методе.
  2. Integer является неизменяемым. Нет такого метода, как Integer#set(i). В противном случае вы можете просто использовать его.

Чтобы заставить его работать, нужно переназначить возвращаемое значение метода inc().

integer = inc(integer);

Чтобы узнать больше о передаче по значению, вот еще один пример:

public static void main(String... args) {
    String[] strings = new String[] { "foo", "bar" };
    changeReference(strings);
    System.out.println(Arrays.toString(strings)); // still [foo, bar]
    changeValue(strings);
    System.out.println(Arrays.toString(strings)); // [foo, foo]
}
public static void changeReference(String[] strings) {
    strings = new String[] { "foo", "foo" };
}
public static void changeValue(String[] strings) {
    strings[1] = "foo";
}
55
ответ дан 7 November 2019 в 07:12
поделиться

1) Только копия ссылки отправляется как значение в формальный параметр. Когда переменной формального параметра присваивают другое значение, ссылочные изменения формального параметра, но ссылка фактического параметра остается тем же, упаковывают этого целочисленного объекта.

общедоступный класс UnderstandingObjects {

public static void main(String[] args) {

    Integer actualParam = new Integer(10);

    changeValue(actualParam);

    System.out.println("Output " + actualParam); // o/p =10

    IntObj obj = new IntObj();

    obj.setVal(20);

    changeValue(obj);

    System.out.println(obj.a); // o/p =200

}

private static void changeValue(Integer formalParam) {

    formalParam = 100;

    // Only the copy of reference is set to the formal parameter
    // this is something like => Integer formalParam =new Integer(100);
    // Here we are changing the reference of formalParam itself not just the
    // reference value

}

private static void changeValue(IntObj obj) {
    obj.setVal(200);

    /*
     * obj = new IntObj(); obj.setVal(200);
     */
    // Here we are not changing the reference of obj. we are just changing the
    // reference obj's value

    // we are not doing obj = new IntObj() ; obj.setValue(200); which has happend
    // with the Integer

}

}

класс IntObj {Целое число a;

public void setVal(int a) {
    this.a = a;
}

}

0
ответ дан 7 November 2019 в 07:12
поделиться

Целое число неизменяемо. Вы можете обернуть int в свой собственный класс-оболочку.

class WrapInt{
    int value;
}

WrapInt theInt = new WrapInt();

inc(theInt);
System.out.println("main: "+theInt.value);
18
ответ дан 7 November 2019 в 07:12
поделиться

Здесь вы видите не перегруженный + опаратор, а поведение автобокса. Класс Integer является неизменным, и ваш код:

Integer i = 0;
i = i + 1;  

рассматривается компилятором (после автобокса) как:

Integer i = Integer.valueOf(0);
i = Integer.valueOf(i.intValue() + 1);  

, поэтому вы правы в своем заключении, что экземпляр Integer изменяется, но не скрытно - это согласуется с определением языка Java: -)

12
ответ дан 7 November 2019 в 07:12
поделиться

Я думаю, что именно автобоксинг сбивает вас с толку.

Эта часть вашего кода:

   public static Integer inc(Integer i) {
        i = i+1;    // I think that this must be **sneakally** creating a new integer...  
        System.out.println("Inc: "+i);
        return i;
    }

На самом деле сводится к коду, который выглядит так:

  public static Integer inc(Integer i) {
        i = new Integer(i) + new Integer(1);      
        System.out.println("Inc: "+i);
        return i;
    }

Что, конечно же... не изменит переданную ссылку.

Вы можете исправить это с помощью чего-то вроде этого

  public static void main(String[] args) {
        Integer integer = new Integer(0);
        for (int i =0; i<10; i++){
            integer = inc(integer);
            System.out.println("main: "+integer);
        }
    }
2
ответ дан 7 November 2019 в 07:12
поделиться

Если вы измените свою функцию inc () на это

 public static Integer inc(Integer i) {
      Integer iParam = i;
      i = i+1;    // I think that this must be **sneakally** creating a new integer...  
      System.out.println(i == iParam);
      return i;
  }

, то вы увидите, что она всегда выводит «false». Это означает, что добавление создает новый экземпляр Integer и сохраняет его в локальной переменной i («local», потому что i на самом деле является копией переданной ссылки), оставляя переменную вызывающей нетронутый метод.

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

i = new Integer(i+1); //actually, you would use Integer.valueOf(i.intValue()+1);

вместо этого это делается автобоксингом.

2
ответ дан 7 November 2019 в 07:12
поделиться

Здесь вы правы:

Integer i = 0;
i = i + 1;  // <- I think that this is somehow creating a new object!

Первое: Integer является неизменяемым.

Второе: класс Integer не переопределяет оператор +, в этой строке задействован автобоксинг и автобоксинг (В старых версиях Java вы бы получили ошибку на вышеуказанной строке).
Когда вы пишете i + 1, компилятор сначала преобразует Integer в (примитив) int для выполнения сложения: автоунбоксинг. Далее, выполняя i = , компилятор преобразует int в (новый) Integer: автобоксинг.
Таким образом, + фактически применяется к примитивным intам.

6
ответ дан 7 November 2019 в 07:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: