{"id":"references-parameters","slug":"values-and-references-as-parameters","title":"Values and references as parameters","text":"Module 10's rule is still the whole story: a parameter gets a copy of the argument. What gets copied depends on the kind of variable. For a primitive it's the value, and for an object it's the reference.\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        int km = 120;\n        Bike bike = new Bike(\"blue\", 120);\n        addToNumber(km);\n        addToBike(bike);\n        System.out.println(km);\n        System.out.println(bike);\n    }\n\n    public static void addToNumber(int km) {\n        km = km + 50;\n    }\n\n    public static void addToBike(Bike bike) {\n        bike.ride(50);\n    }\n}\n// ==== Bike.java ====\npublic class Bike {\n    private String color;\n    private int km;\n\n    public Bike(String color, int km) {\n        this.color = color;\n        this.km = km;\n    }\n\n    public void ride(int km) {\n        this.km = this.km + km;\n    }\n\n    public String toString() {\n        return \"The \" + this.color + \" bike, \" + this.km + \" km\";\n    }\n}\n```\n\n```output\n120\nThe blue bike, 170 km\n```\n\n- `addToNumber` gets a copy of the number 120. It changes its own copy, and `main`'s `km` stays 120.\n- `addToBike` gets a copy of the reference. The copy points at the same bike as `main`'s variable, so `bike.ride(50)` rides `main`'s bike. That's also why a method can change a list or an array it's given, as in modules 14 and 15.\n\n### A new object for the parameter\n\nA method can change the object its parameter points at, but it can't change which object the caller's variable points at. Giving the parameter a new object only moves the parameter's own arrow:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Bike bike = new Bike(\"blue\", 120);\n        replace(bike);\n        System.out.println(bike);\n    }\n\n    public static void replace(Bike bike) {\n        bike = new Bike(\"green\", 0);\n        bike.ride(5);\n        System.out.println(\"In the method: \" + bike);\n    }\n}\n// ==== Bike.java ====\npublic class Bike {\n    private String color;\n    private int km;\n\n    public Bike(String color, int km) {\n        this.color = color;\n        this.km = km;\n    }\n\n    public void ride(int km) {\n        this.km = this.km + km;\n    }\n\n    public String toString() {\n        return \"The \" + this.color + \" bike, \" + this.km + \" km\";\n    }\n}\n```\n\n```output\nIn the method: The green bike, 5 km\nThe blue bike, 120 km\n```\n\nAfter `bike = new Bike(\"green\", 0);` the parameter points at a new green bike, and `ride(5)` rides that one. `main`'s variable was never touched, so it still points at the blue bike. When the caller should end up with a different object, the method returns it and the caller assigns it to its variable: `bike = newBike();`. A method can return an object, as `findOldest` did in module 19.\n\nIn short:\n\n| The parameter's type | The method gets | What the method can change |\n|---|---|---|\n| primitive (`int`, `double`, `boolean`, `char`, ...) | a copy of the value | only its own copy |\n| a class (an object) | a copy of the reference | the object's state, through its methods, but not which object the caller's variable points at |\n","task":"`Jug.java` is ready. In `Main`, write a method `pourAll(Jug from, Jug to)` that pours all the water from one jug into the other: `to` gets everything `from` had, and `from` ends up empty. It returns nothing, since it changes the two jugs themselves. The check runs:\n\n```java\nJug big = new Jug(300);\nJug small = new Jug(150);\npourAll(small, big);\nSystem.out.println(big + \" and \" + small);\n```\n\nand expects:\n\n```\n450 ml and 0 ml\n```\n","kind":"code","seed":"// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Jug big = new Jug(300);\n        Jug small = new Jug(150);\n        pourAll(small, big);\n        System.out.println(big + \" and \" + small);\n    }\n\n    // Write the pourAll method here.\n}\n\n// ==== Jug.java ====\npublic class Jug {\n    private int milliliters;\n\n    public Jug(int milliliters) {\n        this.milliliters = milliliters;\n    }\n\n    public int getMilliliters() {\n        return this.milliliters;\n    }\n\n    public void add(int milliliters) {\n        this.milliliters = this.milliliters + milliliters;\n    }\n\n    public void empty() {\n        this.milliliters = 0;\n    }\n\n    public String toString() {\n        return this.milliliters + \" ml\";\n    }\n}\n","solution":"// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        Jug big = new Jug(300);\n        Jug small = new Jug(150);\n        pourAll(small, big);\n        System.out.println(big + \" and \" + small);\n    }\n\n    public static void pourAll(Jug from, Jug to) {\n        to.add(from.getMilliliters());\n        from.empty();\n    }\n}\n\n// ==== Jug.java ====\npublic class Jug {\n    private int milliliters;\n\n    public Jug(int milliliters) {\n        this.milliliters = milliliters;\n    }\n\n    public int getMilliliters() {\n        return this.milliliters;\n    }\n\n    public void add(int milliliters) {\n        this.milliliters = this.milliliters + milliliters;\n    }\n\n    public void empty() {\n        this.milliliters = 0;\n    }\n\n    public String toString() {\n        return this.milliliters + \" ml\";\n    }\n}\n","hints":["The method changes the jugs through their methods, so it returns nothing: `public static void pourAll(Jug from, Jug to) {`.","Order matters: first `to.add(from.getMilliliters());`, and only then `from.empty();`. Emptying first would pour 0 ml."],"tests":[{"name":"Test 1","stdin":"","call":"Jug big = new Jug(300);\nJug small = new Jug(150);\npourAll(small, big);\nSystem.out.println(big + \" and \" + small);\n","expect":"450 ml and 0 ml","hidden":false},{"name":"Test 2","stdin":"","call":"Jug a = new Jug(0);\nJug b = new Jug(80);\npourAll(b, a);\nSystem.out.println(a + \" and \" + b);\n","expect":"80 ml and 0 ml","hidden":true},{"name":"Test 3","stdin":"","call":"Jug a = new Jug(200);\nJug b = new Jug(100);\nJug c = new Jug(50);\npourAll(a, b);\npourAll(b, c);\nSystem.out.println(a + \", \" + b + \", \" + c);\n","expect":"0 ml, 0 ml, 350 ml","hidden":true}],"require":[],"forbid":[],"more":[{"task":"What does this program print? Watch which aquarium each `add` goes to.\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        int fish = 3;\n        Aquarium tank = new Aquarium(5);\n        stock(tank, fish);\n        System.out.println(fish);\n        System.out.println(tank);\n        swapTank(tank);\n        System.out.println(tank);\n    }\n\n    public static void stock(Aquarium tank, int fish) {\n        tank.add(fish);\n        fish = 0;\n    }\n\n    public static void swapTank(Aquarium tank) {\n        tank.add(1);\n        tank = new Aquarium(20);\n        tank.add(1);\n    }\n}\n// ==== Aquarium.java ====\npublic class Aquarium {\n    private int fish;\n\n    public Aquarium(int fish) {\n        this.fish = fish;\n    }\n\n    public void add(int count) {\n        this.fish = this.fish + count;\n    }\n\n    public String toString() {\n        return \"Aquarium with \" + this.fish + \" fish\";\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        int fish = 3;\n        Aquarium tank = new Aquarium(5);\n        stock(tank, fish);\n        System.out.println(fish);\n        System.out.println(tank);\n        swapTank(tank);\n        System.out.println(tank);\n    }\n\n    public static void stock(Aquarium tank, int fish) {\n        tank.add(fish);\n        fish = 0;\n    }\n\n    public static void swapTank(Aquarium tank) {\n        tank.add(1);\n        tank = new Aquarium(20);\n        tank.add(1);\n    }\n}\n// ==== Aquarium.java ====\npublic class Aquarium {\n    private int fish;\n\n    public Aquarium(int fish) {\n        this.fish = fish;\n    }\n\n    public void add(int count) {\n        this.fish = this.fish + count;\n    }\n\n    public String toString() {\n        return \"Aquarium with \" + this.fish + \" fish\";\n    }\n}\n","hints":["`stock` adds 3 fish to `main`'s aquarium through the reference, so it has 8. `fish = 0;` changes only the method's own copy of the number, so `main`'s `fish` is still 3.","In `swapTank`, the first `tank.add(1)` still goes to `main`'s aquarium. After `tank = new Aquarium(20);` the parameter points at a new aquarium, and the second `add` goes there."],"tests":[{"name":"Output","stdin":"","expect":"3\nAquarium with 8 fish\nAquarium with 9 fish","hidden":false}],"require":[],"forbid":[],"lines":["3","Aquarium with 8 fish","Aquarium with 9 fish"]},{"task":"At the end of each day, `endOfDay` prints the day's steps and should set the step counter back to 0 for the next day. But the second day's total includes the first day's steps too. Fix `endOfDay`: `StepCounter` has a method for this. The program then prints:\n\n```\nToday: 6500 steps\nToday: 3000 steps\n```\n","kind":"code","seed":"// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        StepCounter counter = new StepCounter();\n        counter.walk(4000);\n        counter.walk(2500);\n        endOfDay(counter);\n        counter.walk(3000);\n        endOfDay(counter);\n    }\n\n    public static void endOfDay(StepCounter counter) {\n        System.out.println(\"Today: \" + counter.getSteps() + \" steps\");\n        counter = new StepCounter();\n    }\n}\n\n// ==== StepCounter.java ====\npublic class StepCounter {\n    private int steps;\n\n    public StepCounter() {\n        this.steps = 0;\n    }\n\n    public void walk(int steps) {\n        this.steps = this.steps + steps;\n    }\n\n    public int getSteps() {\n        return this.steps;\n    }\n\n    public void reset() {\n        this.steps = 0;\n    }\n}\n","solution":"// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        StepCounter counter = new StepCounter();\n        counter.walk(4000);\n        counter.walk(2500);\n        endOfDay(counter);\n        counter.walk(3000);\n        endOfDay(counter);\n    }\n\n    public static void endOfDay(StepCounter counter) {\n        System.out.println(\"Today: \" + counter.getSteps() + \" steps\");\n        counter.reset();\n    }\n}\n\n// ==== StepCounter.java ====\npublic class StepCounter {\n    private int steps;\n\n    public StepCounter() {\n        this.steps = 0;\n    }\n\n    public void walk(int steps) {\n        this.steps = this.steps + steps;\n    }\n\n    public int getSteps() {\n        return this.steps;\n    }\n\n    public void reset() {\n        this.steps = 0;\n    }\n}\n","hints":["`counter = new StepCounter();` only points the parameter at a new counter. `main`'s variable still points at the old one, with all its steps.","Reset the counter itself, through the parameter: replace that line with `counter.reset();`."],"tests":[{"name":"The program","stdin":"","expect":"Today: 6500 steps\nToday: 3000 steps","hidden":false},{"name":"Test 2","stdin":"","call":"StepCounter c = new StepCounter();\nc.walk(100);\nendOfDay(c);\nendOfDay(c);\n","expect":"Today: 100 steps\nToday: 0 steps","hidden":true},{"name":"Test 3","stdin":"","call":"StepCounter c = new StepCounter();\nendOfDay(c);\nc.walk(7);\nc.walk(8);\nendOfDay(c);\nSystem.out.println(c.getSteps());\n","expect":"Today: 0 steps\nToday: 15 steps\n0","hidden":true}],"require":[{"pattern":"\\.reset\\s*\\(\\s*\\)","message":"Set the counter itself back to 0 with its `reset()` method."}],"forbid":[{"pattern":"[;{}]\\s*counter\\s*=\\s*new\\b","message":"Giving the parameter a new StepCounter doesn't change `main`'s counter. Reset the counter the parameter points at."}]}]}