scjp проходящий объект - PullRequest
0 голосов
/ 13 сентября 2011
public class Hotel {
    private int roomNr;

    public Hotel(int roomNr) {
        this.roomNr = roomNr;
    }

    public int getRoomNr() {
        return this.roomNr;
    }

    static Hotel doStuff(Hotel hotel) {
        hotel = new Hotel(1);
        return hotel;
    }

    public static void main(String args[]) {
        Hotel h1 = new Hotel(100);
        System.out.print(h1.getRoomNr() + " ");
        Hotel h2 = doStuff(h1);
        System.out.print(h1.getRoomNr() + " ");
        System.out.print(h2.getRoomNr() + " ");
        h1 = doStuff(h2);
        System.out.print(h1.getRoomNr() + " ");
        System.out.print(h2.getRoomNr() + " ");
    }
}

Почему h1 не меняется после вызова doStuff (h1)?Как я понимаю ссылка на объект должна быть передана, а в методе она должна быть заменена на новый объект.

Ответы [ 4 ]

1 голос
/ 13 сентября 2011

Я бы немного определился здесь: вместо того, чтобы говорить, что ссылка передана, думайте о ней как о "ссылке, передаваемой по значению".Таким образом, в основном, метод получает копию ссылки, которая указывает на рассматриваемый объект.Обе ссылки (исходная h1 и новая hotel) указывают на один и тот же объект, но по-прежнему различаются.В этом методе вы изменяете «ссылку», а не объект, на который она ссылается, и, следовательно, результат.

Хорошее чтение может быть это , где автор использует примеры кода на разных языках..

1 голос
/ 13 сентября 2011

В этой части

static Hotel doStuff(Hotel hotel) {
    hotel = new Hotel(1);
    return hotel;
}

переменная hotel - это новая локальная переменная, которая получает справочное значение. Эта новая локальная переменная загружается с новой ссылкой на новый экземпляр Hotel в самой первой строке, и возвращается эта новая ссылка .

Локальная переменная external h1 не изменится.


main:h1 = 0x0000100                     (the old Hotel's address)
       |
     copying
       |
        ------->  doStuff:hotel = 0x0000100  (the method call)
                  doStuff:hotel = 0x0000200  (the new Hotel's address)
                              |
                          copying
                              |
main:h2 = 0x0000200 <---------
0 голосов
/ 13 сентября 2011

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

0 голосов
/ 13 сентября 2011

Потому что объект "передается по значению, а не по ссылке".

То, что передается по значению, это его ссылка.Итак, на ваш взгляд, вы думаете, что он передается по ссылке.

Итак, чтобы было ясно, когда вы передаете объект методу, создается новая «ссылка на указатель», и она передается.Поэтому, если вы измените его, ничего не произойдет.

РЕДАКТИРОВАТЬ: Здесь код

Hotel h1 = new Hotel(100); // h1 holds a reference to a Hotel object in memory
System.out.print(h1.getRoomNr() + " ");
Hotel h2 = doStuff(h1); // when doStuff is called, a new reference pointing to the same object is made, but if you change it, nothing will happen

Взгляните на Core Java .Лучшая книга!

...