Java Packages

In the last lesson you learned about the Java protected access modifier. That word โ€œpackageโ€ kept coming up, so now letโ€™s really understand it. A package is one of the first things you need when a project grows past a handful of files. Letโ€™s learn it.

๐Ÿค” The problem packages solve

One folder with forty Java files breaks in two ways:

  • You cannot find anything. Users, payments, and email files all sit together.
  • Names clash. Your Date, Javaโ€™s Date, and a libraryโ€™s Date fight over one name. The compiler cannot tell which you mean.

A package fixes both. A package is a namespace that groups related classes together, and it gives each class a longer unique name. Think of folders on your computer. Photos go in one folder, invoices in another. Packages do that for your classes.

๐Ÿ“ฆ What a package actually is

A package is two things at once, and they must match:

  • A folder on disk.
  • A name in your code.

You create one with the package declaration at the very top of your file.

package com.shop.users;
public class User {
String name = "Alex";
void greet() {
System.out.println("Hi, I am " + name);
}
}

What that line gives you:

  • The class belongs to the package com.shop.users.
  • Each dot is a folder level.
  • So this file must live in com/shop/users/.
  • The folders on disk must mirror the package name exactly.

Note

The package line must be the first real line of code in the file. Comments can come before it, but no other code can. We will see what happens if you break this rule later.

๐Ÿ—‚๏ธ Folders mirror the package name

Every dot is a folder. For com.shop.users, the files live here:

src/
com/
shop/
users/
User.java
Admin.java
payments/
Payment.java
Card.java

The rules:

  • The name in the code and the path on disk must line up.
  • Put User.java in the wrong folder and the compiler complains.
  • The folder path is the address. Nothing else finds the file.
  • Related classes group together. User and Admin share one folder, Payment and Card get their own.

๐Ÿท๏ธ Naming convention: reverse domain

Use your domain name in reverse, all in lowercase. A company that owns shop.com starts with com.shop, then adds words for the project.

com.shop.users
com.shop.payments
org.redcross.donations
io.github.alex.notes

The reasons and the rules:

  • Domain names are already unique. Nobody else owns shop.com, so two companies never clash.
  • Reversing puts the broadest part first, broad to narrow, like folders.
  • Use all lowercase. com.shop.users, never Com.Shop.Users.
  • Skip Java keywords. com.shop.int fails because int is reserved.
  • Keep parts short and meaningful, so a reader can guess what is inside.

๐ŸŒ Built-in packages you already use

Java ships with many built-in packages, and you have used them since your first program:

  • java.lang holds basics like String, System, Math, Integer. Imported for you automatically.
  • java.util holds tools like Scanner, ArrayList, HashMap, Random.
  • java.io holds classes for reading and writing files and streams.

Other packages you bring in yourself, which is the next lesson. Here is a tiny program that uses a class from java.util.

import java.util.Random;
public class Main {
public static void main(String[] args) {
Random r = new Random();
int roll = r.nextInt(6) + 1; // a number from 1 to 6
System.out.println("You rolled a number from 1 to 6");
}
}

Random lives in java.util, so we ask for it with import.

๐Ÿ”— Fully qualified class names

Every class has a short name and a long name:

  • The short name is just User.
  • The fully qualified name is the package path plus the class name: com.shop.users.User.
  • The long name is always unique, because the package part is unique.
  • Use the short name most of the time. The full name is handy when two classes share a short name.

Here we use java.util.Date by its full name, with no import at all.

public class Main {
public static void main(String[] args) {
java.util.Date now = new java.util.Date();
System.out.println("Created a Date object");
}
}

Output

Created a Date object

The full name told the compiler exactly which Date we mean. No import needed. This is the escape hatch when two Date classes would clash.

โš™๏ธ Compiling and running with packages

Packaged classes need a little care at the command line. Say you have this file at src/com/shop/users/User.java with a main method.

package com.shop.users;
public class User {
public static void main(String[] args) {
System.out.println("Hello from a packaged class");
}
}

Compile with -d to set the output folder.

javac -d out src/com/shop/users/User.java

That builds out/com/shop/users/User.class, mirroring the package as folders again. To run it, give the fully qualified name, not the file path.

java -cp out com.shop.users.User

Output

Hello from a packaged class

The key idea:

  • A packaged class runs by its full dotted name.
  • Use com.shop.users.User, never the file name User.java. The package name is the address Java uses to find it.

Tip

Modern tools like IDEs and build tools such as Maven or Gradle handle all this for you. You will rarely type javac by hand on a real project. But knowing what happens underneath helps you read the errors when something breaks.

โš ๏ธ Common Mistakes

Putting the package statement below other code. The package line must be the first real statement. Only comments may sit above it. The fix: package first, then imports, then the class.

import java.util.Random; // โŒ import before package
package com.shop.users; // โŒ ERROR: class, interface, or enum expected
public class User { }
package com.shop.users; // โœ… package always comes first
import java.util.Random; // โœ… imports come after
public class User { }

Folder path does not match the package name. Declare package com.shop.users; but save the file in a users folder with no com/shop above it, and the compiler cannot match the name to the location. The folders must spell out the full package.

src/
users/
User.java โŒ folder path does not match com.shop.users
src/
com/
shop/
users/
User.java โœ… folder path matches com.shop.users

Leaving classes in the default package. No package line means the class lands in the unnamed โ€œdefault package.โ€

  • Fine for tiny throwaway code.
  • A bad habit for real projects.
  • Classes in a package cannot import default-package classes, so your code stops being reusable.
// โŒ no package line: this class is stuck in the default package
public class User { }
package com.shop.users; // โœ… give every real class a proper package
public class User { }

โœ… Best Practices

  • Give every class a real package. Keep the default package for throwaway tests.
  • Name packages with your reversed domain, lowercase, like com.shop.users.
  • Match the folder structure to the package name, level for level.
  • Group related classes together. The package name should hint at what is inside.
  • Lean on java.lang, java.util, java.io instead of writing your own.
  • Use a fully qualified name only for a real name clash.

๐Ÿ“ What Youโ€™ve Learned

  • A package is a namespace and a folder that groups related classes together.
  • The package declaration must be the first line of code in the file.
  • Packages organize code, avoid name clashes, and shape access (as you saw with protected).
  • The naming convention is reversed domain, lowercase, like com.company.project.
  • The folder structure on disk must mirror the package name, dot for folder.
  • Java ships with built-in packages such as java.lang, java.util, and java.io.
  • A fully qualified name is the package path plus the class name, like com.shop.users.User, and you run a packaged class by that full name.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    Where must the package declaration appear in a Java file?

    Why: The package statement must be the first real statement in the file. Only comments may appear above it, and imports come after it.

  2. 2

    What is the standard naming convention for packages?

    Why: By convention packages use the reversed domain name in lowercase, which keeps names unique worldwide.

  3. 3

    If a class declares package com.shop.users, where must the file live?

    Why: The folder structure must mirror the package name. Each dot is a folder level, so the file lives in com/shop/users.

  4. 4

    What is the fully qualified name of a User class in package com.shop.users?

    Why: The fully qualified name is the full package path plus the class name: com.shop.users.User.

๐Ÿš€ Whatโ€™s Next?

You now know how to group classes into packages and why it matters. But when a class in one package wants to use a class from another package, typing the full name every time gets long. Java gives you a cleaner way to pull in classes from other packages. That is the import statement, and it is what the next lesson is all about. Letโ€™s learn it.

Java Import Statement

Share & Connect