Accessors, Mutators, and Parameters

Instance variables are private, so other classes read and change them through methods. The Canteen class below tracks the water in a hiking canteen, in milliliters.
public class Canteen
{
private int ml;
public Canteen(int start)
{
ml = start;
}
public int getMl()
{
return ml;
}
public boolean isEmpty()
{
return ml == 0;
}
public void refill(int amount)
{
ml = ml + amount;
}
public void drink(int sip)
{
ml = ml - sip;
}
}
Which is which
getMl and isEmpty are accessors. Each returns a value and leaves ml as it was. refill and drink are mutators: each changes ml, and the object is different after the call.
The kind of method is decided by what its body does. Java has no keyword for either kind, and isEmpty counts as an accessor although its name doesn't begin with get.
What an accessor returns is a copy of a value. Take a canteen built with Canteen trail = new Canteen(400);. After int left = trail.getMl();, the variable left holds 400, and it won't change when the canteen does. A later trail.drink(100) leaves the canteen at 300 and left at 400.
Parameters
The amount of water added isn't written into refill; it arrives with each call. In trail.refill(250), the 250 is the argument. The variable amount in the header is the parameter, a variable that exists only while the method runs and starts out holding the argument's value.
Once the call ends, the canteen holds a number, not a link to the caller's variable.
Canteen bottle = new Canteen(400);
int top = 350;
bottle.refill(top);
top = 0;
System.out.println(bottle.getMl());
This prints 750. The canteen stored the sum during the call, and changing top afterward has nothing to reach. A method that assigns to its parameter works the same way in reverse: it changes only its own copy, which disappears when the method ends.
Preconditions
Some methods work only for certain arguments. A precondition is something the caller has to guarantee before calling the method. It's usually written as a comment above the header.
// Precondition: sip <= getMl()
public void drink(int sip)
The method doesn't check it; meeting it is the caller's job. A call that breaks it, like a 500-milliliter sip from a canteen holding 400, leaves the water level at -100.