{"id":"packages-package-line","slug":"package-line","title":"Packages: classes in folders","text":"Every program so far kept its files side by side: `Main.java`, `Heater.java`, `BankAccount.java`, all at the top. That's fine for five classes. A real program can have hundreds, and Java sorts them into **packages**: named groups of classes that belong together, each package in a folder of its own.\n\nYou've used packages since module 2. `import java.util.Scanner;` names the class `Scanner` of the package `java.util`, which holds Scanner, the lists, the maps and many other tools of Java's library. This module puts your own classes in packages.\n\n### The package line\n\nA quiz app has questions, and each question checks the player's reply. Here's the start of the class `Question`, in the package `quiz.domain`:\n\n```java\npackage quiz.domain;\n\npublic class Question {\n    ...\n}\n```\n\n- The first line of code says which package the class is in: `package quiz.domain;`. Only comments may come before it.\n- The file's folders match the package. Each part of the name is a folder, and the dot goes one folder deeper: `Question.java` is in the folder `domain`, which is in the folder `quiz`. The file's path in the program is `quiz/domain/Question.java`.\n- Package names are written in small letters, by custom everywhere, and this site requires it. On this site, a folder name is a Java name that starts with a small letter, followed by small letters, digits or `_`, and it can't be a word Java reserves, such as `class` or `new`.\n- The word *domain* is often used for the classes of the things a program is about, here the questions. Step 4 comes back to it.\n\n### A class's full name\n\nHere's the whole program. `Main.java` stays where it has always been, at the top, with no package line:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        quiz.domain.Question question = new quiz.domain.Question(\"Which planet is the largest?\", \"Jupiter\", 2);\n        System.out.println(question);\n        System.out.println(question.isRight(\" jupiter\"));\n        System.out.println(question.isRight(\"Saturn\"));\n        System.out.println(question.getClass().getName());\n    }\n}\n// ==== quiz/domain/Question.java ====\npackage quiz.domain;\n\npublic class Question {\n    private String prompt;\n    private String answer;\n    private int points;\n\n    public Question(String prompt, String answer, int points) {\n        this.prompt = prompt;\n        this.answer = answer;\n        this.points = points;\n    }\n\n    public boolean isRight(String reply) {\n        return reply.trim().equalsIgnoreCase(this.answer);\n    }\n\n    public int getPoints() {\n        return this.points;\n    }\n\n    @Override\n    public String toString() {\n        return this.prompt + \" (\" + this.points + \" points)\";\n    }\n}\n```\n\n```output\nWhich planet is the largest? (2 points)\ntrue\nfalse\nquiz.domain.Question\n```\n\n- A class's **full name** is its package, a dot and its own name: `quiz.domain.Question`. Main is in another package, so here it writes the full name, both as the variable's type and after `new`. Step 2 shows a shorter way.\n- `getClass().getName()` (module 34) gives the object's class by its full name.\n- Inside its package, Question is written like every class you've written: instance variables, a constructor and methods. Only the first line is new.\n- `isRight` removes spaces around the reply with `trim()` and ignores capital letters, so ` jupiter` counts.\n- Question, its constructor and its methods are `public`, so Main, in another package, can use them. Step 3 explains why that matters.\n\nA full name tells apart classes that share a simple name. A survey app could have its own class `Question` in a package `survey`: `survey.Question` and `quiz.domain.Question` are two different classes, and one program can use both. Java's own library has two types called `List`, for example: the interface `java.util.List` of module 35, and the class `java.awt.List`, a list shown in a window.\n\n### The default package\n\nEvery class you wrote before this module had no package line. A class without one is in the **default package**, a package without a name, and its full name is just its own name: `Heater`, `Main`. On this site, `Main` always stays there, at the top of the program, because the site starts every program from the class `Main`.\n\nClasses of the same package use each other by their simple names, with nothing more. That's why your classes could always use each other: they were all in the default package. Inside `quiz.domain` it's the same: a class `Round` in that package could simply write `Question`.\n\n### Files in folders on this site\n\nIn a challenge, each file has a tab of its own, and a file in a folder shows its folders above its name, in small letters: `quiz/domain/` over `Question.java`. javac's messages name a file by its path, such as `quiz/domain/Question.java`.\n","task":"A shoe store's program keeps its classes in the package `shoestore.domain`. `Main.java` is ready: it uses the class `Shoe` by its full name. In `shoestore/domain/Shoe.java`, start with the package line, and then write the class `Shoe`, with:\n\n- a constructor `Shoe(String model, int size)`\n- `getSize()`, which returns the size\n- `toString()`, which returns the model and the size, like `Trail runner, size 42`\n\nThe program prints:\n\n```\nTrail runner, size 42\n42\nshoestore.domain.Shoe\n```\n","kind":"code","seed":"// ==== shoestore/domain/Shoe.java ====\n// Write the package line first, then the class Shoe.\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        shoestore.domain.Shoe shoe = new shoestore.domain.Shoe(\"Trail runner\", 42);\n        System.out.println(shoe);\n        System.out.println(shoe.getSize());\n        System.out.println(shoe.getClass().getName());\n    }\n}\n","solution":"// ==== shoestore/domain/Shoe.java ====\npackage shoestore.domain;\n\npublic class Shoe {\n    private String model;\n    private int size;\n\n    public Shoe(String model, int size) {\n        this.model = model;\n        this.size = size;\n    }\n\n    public int getSize() {\n        return this.size;\n    }\n\n    @Override\n    public String toString() {\n        return this.model + \", size \" + this.size;\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        shoestore.domain.Shoe shoe = new shoestore.domain.Shoe(\"Trail runner\", 42);\n        System.out.println(shoe);\n        System.out.println(shoe.getSize());\n        System.out.println(shoe.getClass().getName());\n    }\n}\n","hints":["The file is in the folder `shoestore/domain/`, so its first line is `package shoestore.domain;`. After it comes the class, written as always: `public class Shoe {`.","Give Shoe two instance variables, the model and the size, and set them in the constructor. `toString` returns `this.model + \", size \" + this.size`."],"tests":[{"name":"The program's output","stdin":"","expect":"Trail runner, size 42\n42\nshoestore.domain.Shoe","hidden":false},{"name":"Test 2","stdin":"","call":"Shoe boot = new Shoe(\"Winter boot\", 39);\nSystem.out.println(boot);\nSystem.out.println(boot.getSize() + 1);\n","expect":"Winter boot, size 39\n40","hidden":true},{"name":"Test 3","stdin":"","call":"shoestore.domain.Shoe sandal = new shoestore.domain.Shoe(\"Sandal\", 37);\nSystem.out.println(sandal.getClass().getName() + \": \" + sandal);\n","expect":"shoestore.domain.Shoe: Sandal, size 37","hidden":true}],"require":[{"pattern":"\\bpackage\\s+shoestore\\.domain\\s*;","message":"Start `Shoe.java` with the line `package shoestore.domain;`: the file is in the folder `shoestore/domain/`."}],"forbid":[],"more":[{"task":"A school has lockers in its halls and in its gym, and its program has two classes called `Locker`: one in the default package, next to `Main`, and one in the package `school.gym`. What does this program print?\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        school.gym.Locker gymLocker = new school.gym.Locker(14);\n        Locker hallLocker = new Locker(14);\n        gymLocker.lock();\n        System.out.println(gymLocker);\n        System.out.println(hallLocker);\n        System.out.println(gymLocker.getClass().getName());\n        System.out.println(hallLocker.getClass().getName());\n    }\n}\n// ==== Locker.java ====\npublic class Locker {\n    private int number;\n\n    public Locker(int number) {\n        this.number = number;\n    }\n\n    @Override\n    public String toString() {\n        return \"Hall locker \" + this.number;\n    }\n}\n// ==== school/gym/Locker.java ====\npackage school.gym;\n\npublic class Locker {\n    private int number;\n    private boolean locked;\n\n    public Locker(int number) {\n        this.number = number;\n        this.locked = false;\n    }\n\n    public void lock() {\n        this.locked = true;\n    }\n\n    @Override\n    public String toString() {\n        if (this.locked) {\n            return \"Gym locker \" + this.number + \", locked\";\n        }\n        return \"Gym locker \" + this.number + \", open\";\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        school.gym.Locker gymLocker = new school.gym.Locker(14);\n        Locker hallLocker = new Locker(14);\n        gymLocker.lock();\n        System.out.println(gymLocker);\n        System.out.println(hallLocker);\n        System.out.println(gymLocker.getClass().getName());\n        System.out.println(hallLocker.getClass().getName());\n    }\n}\n// ==== Locker.java ====\npublic class Locker {\n    private int number;\n\n    public Locker(int number) {\n        this.number = number;\n    }\n\n    @Override\n    public String toString() {\n        return \"Hall locker \" + this.number;\n    }\n}\n// ==== school/gym/Locker.java ====\npackage school.gym;\n\npublic class Locker {\n    private int number;\n    private boolean locked;\n\n    public Locker(int number) {\n        this.number = number;\n        this.locked = false;\n    }\n\n    public void lock() {\n        this.locked = true;\n    }\n\n    @Override\n    public String toString() {\n        if (this.locked) {\n            return \"Gym locker \" + this.number + \", locked\";\n        }\n        return \"Gym locker \" + this.number + \", open\";\n    }\n}\n","hints":["`Locker` on its own, with no package, means the Locker of Main's own package: the default one, in `Locker.java` at the top. The full name `school.gym.Locker` means the other class.","`getName()` gives the full name of the object's class: with its package for the gym's locker, and just `Locker` for the class in the default package."],"tests":[{"name":"Output","stdin":"","expect":"Gym locker 14, locked\nHall locker 14\nschool.gym.Locker\nLocker","hidden":false}],"require":[],"forbid":[],"lines":["Gym locker 14, locked","Hall locker 14","school.gym.Locker","Locker"]},{"task":"A beekeeper's program keeps its classes in the folder `apiary/domain/`, for the package `apiary.domain`, but it doesn't compile: the package lines of both files are wrong. `Hive.java` has none, and `Harvest.java` names only part of the package. javac prints many messages for this. The telling one is `file does not contain class apiary.domain.Hive`: javac looked for the class in the folder of its package, and found a file whose package line is missing or says something else.\n\nFix the first line of code of each file so that it matches the file's folder. In `Hive.java`, the package line comes first, before the import. Don't change `Main.java`. The program should print:\n\n```\nLinden: 2 harvests, 7300 grams\napiary.domain.Hive\n```\n","kind":"code","seed":"// ==== apiary/domain/Hive.java ====\nimport java.util.ArrayList;\n\npublic class Hive {\n    private String name;\n    private ArrayList<Harvest> harvests;\n\n    public Hive(String name) {\n        this.name = name;\n        this.harvests = new ArrayList<>();\n    }\n\n    public void add(Harvest harvest) {\n        this.harvests.add(harvest);\n    }\n\n    public int totalGrams() {\n        int total = 0;\n        for (Harvest harvest : this.harvests) {\n            total += harvest.getGrams();\n        }\n        return total;\n    }\n\n    @Override\n    public String toString() {\n        return this.name + \": \" + this.harvests.size() + \" harvests, \" + this.totalGrams() + \" grams\";\n    }\n}\n\n// ==== apiary/domain/Harvest.java ====\npackage apiary;\n\npublic class Harvest {\n    private String month;\n    private int grams;\n\n    public Harvest(String month, int grams) {\n        this.month = month;\n        this.grams = grams;\n    }\n\n    public int getGrams() {\n        return this.grams;\n    }\n\n    @Override\n    public String toString() {\n        return this.month + \": \" + this.grams + \" grams\";\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        apiary.domain.Hive hive = new apiary.domain.Hive(\"Linden\");\n        hive.add(new apiary.domain.Harvest(\"June\", 4200));\n        hive.add(new apiary.domain.Harvest(\"August\", 3100));\n        System.out.println(hive);\n        System.out.println(hive.getClass().getName());\n    }\n}\n","solution":"// ==== apiary/domain/Hive.java ====\npackage apiary.domain;\n\nimport java.util.ArrayList;\n\npublic class Hive {\n    private String name;\n    private ArrayList<Harvest> harvests;\n\n    public Hive(String name) {\n        this.name = name;\n        this.harvests = new ArrayList<>();\n    }\n\n    public void add(Harvest harvest) {\n        this.harvests.add(harvest);\n    }\n\n    public int totalGrams() {\n        int total = 0;\n        for (Harvest harvest : this.harvests) {\n            total += harvest.getGrams();\n        }\n        return total;\n    }\n\n    @Override\n    public String toString() {\n        return this.name + \": \" + this.harvests.size() + \" harvests, \" + this.totalGrams() + \" grams\";\n    }\n}\n\n// ==== apiary/domain/Harvest.java ====\npackage apiary.domain;\n\npublic class Harvest {\n    private String month;\n    private int grams;\n\n    public Harvest(String month, int grams) {\n        this.month = month;\n        this.grams = grams;\n    }\n\n    public int getGrams() {\n        return this.grams;\n    }\n\n    @Override\n    public String toString() {\n        return this.month + \": \" + this.grams + \" grams\";\n    }\n}\n\n// ==== Main.java ====\npublic class Main {\n    public static void main(String[] args) {\n        apiary.domain.Hive hive = new apiary.domain.Hive(\"Linden\");\n        hive.add(new apiary.domain.Harvest(\"June\", 4200));\n        hive.add(new apiary.domain.Harvest(\"August\", 3100));\n        System.out.println(hive);\n        System.out.println(hive.getClass().getName());\n    }\n}\n","hints":["Both files are in the folder `apiary/domain/`, so both start with the same line: `package apiary.domain;`. `package apiary;` would be right only for a file in the folder `apiary/` itself.","In `Hive.java`, put `package apiary.domain;` on the very first line, above `import java.util.ArrayList;`. Hive uses Harvest without an import: once both are in `apiary.domain`, they're in the same package."],"tests":[{"name":"The program's output","stdin":"","expect":"Linden: 2 harvests, 7300 grams\napiary.domain.Hive","hidden":false},{"name":"Test 2","stdin":"","call":"Hive clover = new Hive(\"Clover\");\nSystem.out.println(clover);\nclover.add(new Harvest(\"May\", 950));\nSystem.out.println(clover + \" / \" + new Harvest(\"July\", 2800));\n","expect":"Clover: 0 harvests, 0 grams\nClover: 1 harvests, 950 grams / July: 2800 grams","hidden":true}],"require":[{"pattern":"\\bpackage\\s+apiary\\.domain\\s*;","min":2,"message":"Both files are in the folder `apiary/domain/`, so each starts with `package apiary.domain;`."}],"forbid":[]}]}