{"id":"references-objects","slug":"reference-variables","title":"Reference variables","text":"Module 14 showed that a list variable doesn't hold the list itself, but a **reference** to it: where the list is in the computer's memory. That's true of every variable whose type is a class, not only of lists. A `Bike` variable doesn't hold a bike. It holds a reference that leads to a Bike object, and the object itself is somewhere else in memory.\n\n`new` creates the object and gives back a reference to it, and `=` stores that reference in the variable. Picture the variable holding an arrow that points at the object.\n\n### Two variables, one object\n\nAssigning one reference variable to another copies the reference (the arrow), not the object. Both variables then point at the same object, and a change made through one of them shows through the other:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Bike mine = new Bike(\"blue\", 120);\n        Bike borrowed = mine;\n        borrowed.ride(35);\n        System.out.println(mine);\n        System.out.println(borrowed);\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\nThe blue bike, 155 km\nThe blue bike, 155 km\n```\n\n- There's only one `new`, so there's only one bike. `Bike borrowed = mine;` gives it a second name. It's like lending your bike to a friend: they don't get a bike of their own, they ride yours.\n- `borrowed.ride(35)` changes that one bike, and `mine` shows the new kilometers too.\n\nFor two separate bikes you need two `new`s. `Bike borrowed = new Bike(\"blue\", 120);` builds a second bike that only looks the same, and riding it leaves yours alone.\n\n### Pointing somewhere else, and ==\n\nFor objects, `==` compares the references: it's `true` when both sides point at the very same object. And assigning a new reference to a variable changes where that variable points, while the object it pointed at before stays as it was:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Bike mine = new Bike(\"blue\", 120);\n        Bike borrowed = mine;\n        System.out.println(mine == borrowed);\n        borrowed = new Bike(\"blue\", 120);\n        System.out.println(mine == borrowed);\n        borrowed.ride(10);\n        System.out.println(mine);\n        System.out.println(borrowed);\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\ntrue\nfalse\nThe blue bike, 120 km\nThe blue bike, 130 km\n```\n\n- At first both variables point at the same bike, so `mine == borrowed` is `true`.\n- `borrowed = new Bike(\"blue\", 120);` points `borrowed` at a new bike. The two bikes have the same color and kilometers, but they're two objects, so now `mine == borrowed` is `false`.\n- `borrowed.ride(10)` rides the new bike, and `mine` still points at the old one, unchanged.\n\nKeep the two apart: `borrowed.ride(10)` changes the object that `borrowed` points at, while `borrowed = ...` changes the variable, and no object changes. An object that nothing refers to any more (no variable, no list, no other object) can't be reached by the program. Java's **garbage collector** may free its memory later, though it may also never get around to it before the program ends.\n\nWhether two different objects hold the same values is a question for a method called `equals`, which your own classes get in module 23. It's the same reason Strings are compared with `equals`, not with `==`.\n\n### Strings are objects too\n\nA String variable holds a reference as well. But a String can never be changed once it exists: `toUpperCase()` and `trim()` return their result, and `+` makes a new String, while the String you started with stays as it was. So two variables that share one String never notice each other:\n\n```java\nString first = \"tea\";\nString second = first;\nsecond = second + \" with milk\";\nSystem.out.println(first);\nSystem.out.println(second);\n```\n\n```output\ntea\ntea with milk\n```\n\n`second + \" with milk\"` makes a new String, and `second` is pointed at it. `first` still points at `\"tea\"`.\n","task":"What does this program print? Count the `new`s first: that's how many batteries there are.\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        Battery phone = new Battery(100);\n        Battery camera = new Battery(100);\n        Battery spare = phone;\n        phone.use(30);\n        spare.use(20);\n        camera.use(5);\n        spare = camera;\n        spare.use(10);\n        System.out.println(phone);\n        System.out.println(camera);\n        System.out.println(phone == spare);\n    }\n}\n// ==== Battery.java ====\npublic class Battery {\n    private int percent;\n\n    public Battery(int percent) {\n        this.percent = percent;\n    }\n\n    public void use(int amount) {\n        this.percent = this.percent - amount;\n    }\n\n    public String toString() {\n        return this.percent + \"%\";\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        Battery phone = new Battery(100);\n        Battery camera = new Battery(100);\n        Battery spare = phone;\n        phone.use(30);\n        spare.use(20);\n        camera.use(5);\n        spare = camera;\n        spare.use(10);\n        System.out.println(phone);\n        System.out.println(camera);\n        System.out.println(phone == spare);\n    }\n}\n// ==== Battery.java ====\npublic class Battery {\n    private int percent;\n\n    public Battery(int percent) {\n        this.percent = percent;\n    }\n\n    public void use(int amount) {\n        this.percent = this.percent - amount;\n    }\n\n    public String toString() {\n        return this.percent + \"%\";\n    }\n}\n","hints":["There are two batteries. At first `spare` points at the phone's battery, so both `phone.use(30)` and `spare.use(20)` use that one.","`spare = camera;` points `spare` at the camera's battery, so `spare.use(10)` uses the camera's. After that, `phone` and `spare` point at different batteries."],"tests":[{"name":"Output","stdin":"","expect":"50%\n85%\nfalse","hidden":false}],"require":[],"forbid":[],"lines":["50%","85%","false"],"more":[{"task":"Ana and Ben each have a piggy bank. The program reads how much Ana puts in hers and then how much Ben puts in his, and prints both piggy banks. But it prints the same piggy bank twice, with both amounts in it. Find the line that leaves Ben without a piggy bank of his own, and fix it. For the input `5` and `3` the program prints:\n\n```\nAna: 5 euros\nBen: 3 euros\n```\n","kind":"code","seed":"// ==== Main.java ====\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        PiggyBank ana = new PiggyBank(\"Ana\");\n        PiggyBank ben = ana;\n        ana.deposit(Integer.valueOf(scanner.nextLine()));\n        ben.deposit(Integer.valueOf(scanner.nextLine()));\n        System.out.println(ana);\n        System.out.println(ben);\n    }\n}\n\n// ==== PiggyBank.java ====\npublic class PiggyBank {\n    private String owner;\n    private int euros;\n\n    public PiggyBank(String owner) {\n        this.owner = owner;\n        this.euros = 0;\n    }\n\n    public void deposit(int euros) {\n        this.euros = this.euros + euros;\n    }\n\n    public String toString() {\n        return this.owner + \": \" + this.euros + \" euros\";\n    }\n}\n","solution":"// ==== Main.java ====\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        PiggyBank ana = new PiggyBank(\"Ana\");\n        PiggyBank ben = new PiggyBank(\"Ben\");\n        ana.deposit(Integer.valueOf(scanner.nextLine()));\n        ben.deposit(Integer.valueOf(scanner.nextLine()));\n        System.out.println(ana);\n        System.out.println(ben);\n    }\n}\n\n// ==== PiggyBank.java ====\npublic class PiggyBank {\n    private String owner;\n    private int euros;\n\n    public PiggyBank(String owner) {\n        this.owner = owner;\n        this.euros = 0;\n    }\n\n    public void deposit(int euros) {\n        this.euros = this.euros + euros;\n    }\n\n    public String toString() {\n        return this.owner + \": \" + this.euros + \" euros\";\n    }\n}\n","hints":["`PiggyBank ben = ana;` doesn't build a piggy bank. It copies the reference, so `ben` points at Ana's.","Build Ben his own with `new`: `PiggyBank ben = new PiggyBank(\"Ben\");`."],"tests":[{"name":"Test 1","stdin":"5\n3\n","expect":"Ana: 5 euros\nBen: 3 euros","hidden":false},{"name":"Test 2","stdin":"10\n0\n","expect":"Ana: 10 euros\nBen: 0 euros","hidden":true},{"name":"Test 3","stdin":"0\n12\n","expect":"Ana: 0 euros\nBen: 12 euros","hidden":true},{"name":"Test 4","stdin":"7\n7\n","expect":"Ana: 7 euros\nBen: 7 euros","hidden":true}],"require":[{"pattern":"\\bnew\\s+PiggyBank\\s*\\(","min":2,"message":"Ben needs a piggy bank of his own: create it with `new PiggyBank(\"Ben\")`."}],"forbid":[]},{"task":"In a quiz, two teams answer in turns, red first. The program reads the points for each answer, one per line, until `end`: the first answer is red's, the second blue's, the third red's again, and so on. `Main` already has a variable `current` that points at the team whose turn it is. For each answer, add the points with `current.addPoints(...)`, then point `current` at the other team, using `==` to see which team it points at now. At the end, print both teams. For the input `3`, `2`, `4`, `1` and `end`, one per line, the program prints:\n\n```\nRed: 7 points\nBlue: 3 points\n```\n","kind":"code","seed":"// ==== Main.java ====\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        Team red = new Team(\"Red\");\n        Team blue = new Team(\"Blue\");\n        Team current = red;\n\n        System.out.println(red);\n        System.out.println(blue);\n    }\n}\n\n// ==== Team.java ====\npublic class Team {\n    private String name;\n    private int points;\n\n    public Team(String name) {\n        this.name = name;\n        this.points = 0;\n    }\n\n    public void addPoints(int points) {\n        this.points = this.points + points;\n    }\n\n    public String toString() {\n        return this.name + \": \" + this.points + \" points\";\n    }\n}\n","solution":"// ==== Main.java ====\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        Team red = new Team(\"Red\");\n        Team blue = new Team(\"Blue\");\n        Team current = red;\n        while (true) {\n            String line = scanner.nextLine();\n            if (line.equals(\"end\")) {\n                break;\n            }\n            current.addPoints(Integer.valueOf(line));\n            if (current == red) {\n                current = blue;\n            } else {\n                current = red;\n            }\n        }\n        System.out.println(red);\n        System.out.println(blue);\n    }\n}\n\n// ==== Team.java ====\npublic class Team {\n    private String name;\n    private int points;\n\n    public Team(String name) {\n        this.name = name;\n        this.points = 0;\n    }\n\n    public void addPoints(int points) {\n        this.points = this.points + points;\n    }\n\n    public String toString() {\n        return this.name + \": \" + this.points + \" points\";\n    }\n}\n","hints":["In a `while (true)` loop: read a line, `break` at `end`, and otherwise `current.addPoints(Integer.valueOf(line));`. The points go to whichever team `current` points at.","Then pass the turn: `if (current == red) { current = blue; } else { current = red; }`. That only changes where `current` points, and both teams keep their points."],"tests":[{"name":"Test 1","stdin":"3\n2\n4\n1\nend\n","expect":"Red: 7 points\nBlue: 3 points","hidden":false},{"name":"Test 2","stdin":"5\nend\n","expect":"Red: 5 points\nBlue: 0 points","hidden":true},{"name":"Test 3","stdin":"end\n","expect":"Red: 0 points\nBlue: 0 points","hidden":true},{"name":"Test 4","stdin":"1\n2\n3\nend\n","expect":"Red: 4 points\nBlue: 2 points","hidden":true}],"require":[{"pattern":"\\bcurrent\\.addPoints\\s*\\(","message":"Add the points to the team whose turn it is: `current.addPoints(...)`."},{"pattern":"\\bcurrent\\s*[=!]=|[=!]=\\s*current\\b","message":"Use `==` to see which team `current` points at, as in `if (current == red)`."}],"forbid":[{"pattern":"\\b(red|blue)\\.addPoints\\s*\\(","message":"Add the points through `current`, not through `red` or `blue` directly."}]}]}