views:

185

answers:

5

Why does the following code return 100 100 1 1 1 and not 100 1 1 1 1 ?

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() + " ");
}
}

Why does it appear to pass Hotel by-value to doStuff() ?

+4  A: 

Because Java does pass by value. Only in this case, the value is a reference to a Hotel object. Or to be more clear, Java passes a reference to the same Object that h1 points to. Therefore, h1 itself is not modified.

Justin Ardini
+5  A: 

Reference to Hotel is passed by value.

Roman
+6  A: 

It does exactly what you told it do do :-)

Hotel h1 = new Hotel(100);
System.out.print(h1.getRoomNr() + " "); // 100
Hotel h2 = doStuff(h1);
System.out.print(h1.getRoomNr() + " "); // 100 - h1 is not changed, h2 is a distinct new object
System.out.print(h2.getRoomNr() + " "); // 1
h1 = doStuff(h2);
System.out.print(h1.getRoomNr() + " "); // 1 - h1 is now changed, h2 not
System.out.print(h2.getRoomNr() + " "); // 1

As others noted (and is explained very clearly in this article), Java passes by value. In this case, it passes a copy of the reference h1 to doStuff. There the copy gets overwritten with a new reference (which is then returned and assigned to h2), but the original value of h1 is not affected: it still references the first Hotel object with a room number of 100.

Péter Török
+1  A: 

The Hotel reference is passed by value. You're only changing the local hotel variable in the doStuff method and returning it, not changing the original h1. You could change the original h1 from within the method if you had a setRoomNr method and called hotel.setRoomNr(1) though...

froadie
+2  A: 

It is doing fine. Inside static Hotel doStuff(Hotel hotel), you are creating a new instance of of Hotel, old hotel reference is unchanged.

fastcodejava