Передача переменной типа ссылки в качестве параметра метода - PullRequest
3 голосов
/ 30 января 2010

После запуска кода ниже я получаю этот вывод: Ева 1200

Может ли кто-нибудь объяснить мне, почему значение переменной типа Person изменяется, а значение переменной типа Integer - нет? Я уже прочитал это:

  1. www.javaworld.com / JavaWorld / javaqa / 2000-05 / 03-QA-0526-pass.html
  2. www.yoda.arachsys.com / Java / passing.html # формальный

но я не понимаю, почему с типами Person и Integer это работает по-разному.

public class Test {
    public static void main(String[] args) {
        Object person = new Person("Adam");
        Object integer = new Integer("1200");

        changePerson(person);
        changeInteger(integer);

        System.out.println(person);
        System.out.println(integer);
    }

    private static void changeInteger(Object integer) {
        integer = 1000;
    }

    private static void changePerson(Object person) {
        ((Person)person).name="Eve"; 
    }
}

Ответы [ 7 ]

3 голосов
/ 30 января 2010

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

Если вы передадите примитив , то значение будет скопировано , если вы передадите ссылочный тип , адрес будет скопирован , отсюда и различия.

Если вы перейдете по этим ссылкам выше и / или немного погуглите, вы узнаете больше.

2 голосов
/ 30 января 2010

В случае Integer вы изменяете значение самого параметра (который является локальным для метода). В случае Person вы изменяете значение поля внутри параметра. Это поле является частью объекта, и поэтому оно является видимым для вызывающей стороны.

1 голос
/ 13 апреля 2015

Просто для любой будущей ссылки, принятый ответ не является правильным ответом в этом случае (хотя ссылки предоставляют достаточно информации, чтобы получить правильный ответ). Проблема OP не имеет ничего общего с примитивами против объектов. В приведенном коде экзамена нет используемых примитивов, и целое число, и персона являются полными объектами. Ответы ниже этого ответа более полезны. Ключ в том, что переменной параметра (то есть переменной, используемой для хранения переданного параметра в методах) присваивается текущее значение переменной, используемой в вызове метода. Объекты хранятся по ссылке в Java, поэтому они указывают на объект, а не хранят объект напрямую. Таким образом, переменная параметра в методе получает этот адрес указателя и использует его для доступа к деталям объекта. Таким образом, если метод изменяет объект, это тот же объект, на который указывает вызывающий код, и поэтому оба места увидят это изменение. В целочисленном примере, когда вы говорите, что integer = 1000, он перезаписывает переданный указатель новым указателем на новый объект Integer - вы потеряли соединение с исходным объектом.

Обратите внимание, что невозможно изменить объект Integer после того, как он был создан (например, нет .setValue () метод), поэтому невозможно написать код способом, который мог бы изменить исходный объект Integer.

1 голос
/ 30 января 2010

В changeInteger(), когда вы делаете целое число = 1000, создается новый объект и ему присваивается локальная переменная целое число . Так что если вы делаете

person = new Person();
person.name="Eve";

в changePerson()

вы получите то же поведение, что и для целых чисел.

PS: старые ссылки теряются, когда вы назначаете их вновь созданным объектам внутри функции.

0 голосов
/ 30 января 2010

В changePerson () вы сами изменяете данный объект через его свойство public name. В changeInteger () вы изменяете локальный объект Integer;

Положить System.out.println (целое число); внутри функции changeInteger (), и вы увидите, что Integer изменяется, но только в области действия функции.

private static void changeInteger(Object integer) {
    integer = 1000;
    System.out.println(integer);
}
0 голосов
/ 30 января 2010

В методе changeInteger() вы назначаете совершенно новый объект (1000) для ссылочной переменной integer. Но ссылочная переменная integer в методе main() по-прежнему указывает на старый объект (1200). Таким образом, оператор print () в методе main () печатает старое значение (1200)

Однако в методе changePerson() ссылочная переменная person по-прежнему указывает на старый объект. Просто значение одного из его полей меняется.

Кроме того, имейте в виду, что Integer (как и другие примитивные оболочки) изменчив. Каждый раз, когда вам нужно назначить новое значение для ref var, JDK создаст совершенно новый объект.

Надеюсь, это поможет!

0 голосов
/ 30 января 2010

Ваш код ниже компилируется? Для этого нужен актерский состав.

private static void changeInteger(Object integer) {
    integer = 1000;
}

Ваш integer будет изменен, если он был встроен в другой object, например. Person.

РЕДАКТИРОВАТЬ:

Неверно в вопросе компиляции. В Java ссылки копируются по значению. Таким образом, в первом случае ссылка указывается на другую память. Во втором случае name входит в состав Person. Поскольку вы меняете имя с помощью Person без изменения Person, изменение в name отражается вне метода. Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...