Passing and Returning Object References

When an argument refers to an object, the method can reach that object through its parameter, and no second object is made. Here the object is a Bicycle.
public class Bicycle
{
private int gear;
public Bicycle(int g)
{
gear = g;
}
public void shiftUp()
{
gear++;
}
public int getGear()
{
return gear;
}
}
Two kinds of change
A bike shop's Mechanic class has this method, which takes a bike and a spare.
public void swapIn(Bicycle b, Bicycle spare)
{
b.shiftUp();
b = spare;
b.shiftUp();
}
Bicycle commuter = new Bicycle(5);
Bicycle loaner = new Bicycle(2);
Mechanic shop = new Mechanic();
shop.swapIn(commuter, loaner);
System.out.println(commuter.getGear() + " " + loaner.getGear());
The output is 6 3. The parameter b begins with the reference held by commuter, so the first shiftUp takes the commuter's bike from gear 5 to 6. Then b = spare; changes only b, which now refers to the loaner, and commuter still refers to its own bike. The second shiftUp reaches the loaner and raises it from 2 to 3.
Returning a reference
A return statement whose value is a reference returns the reference itself, so the object isn't copied on the way out. A Rack class that keeps a Bicycle in a private field and returns it from getBike() hands every caller the same object: rack.getBike() == rack.getBike() is true. Any code that gets that reference can call shiftUp on the rack's bike, even though the field is private. A class that must keep control of an object can offer methods that report on it, such as one returning the bike's gear, instead of returning the object.
Private data of the same class
Inside Bicycle, a method can read the private instance variables of another Bicycle passed to it.
public boolean sameGearAs(Bicycle other)
{
return gear == other.gear;
}
The expression other.gear compiles because the method belongs to Bicycle and other is a Bicycle. In Mechanic, the same expression wouldn't compile, and a method there has to call other.getGear() instead.