Week 1

Environment setup

How Java works

Types and Variables

Arrays

Basic IO

Control Flow

Packages

OOP in Java

Static Members

Practice

Assignment

Back end Track

🎯 Learning Objectives

By the end of this module, you will be able to:


1. What is a Package?

As your program grows, you'll end up with many classes. Without any organisation, they all pile up in the same place — making the codebase hard to navigate and increasing the chance of name conflicts.

A package is a way to group related classes together under a common namespace. Think of it like a folder system for your classes.

🔍 Coming from JavaScript/Node.js, you're used to organising code into separate files and folders, then connecting them with import/require. Java packages serve the same purpose — the main difference is that Java formalises this structure as a first-class language feature, not just a file system convention.

A real-world Java project might be organised like this:

com.bookstore
├── model        → Book, Author, Customer
├── service      → BookService, OrderService
├── repository   → BookRepository
└── util         → PriceFormatter, DateHelper

Each of these groups is a package. Classes inside model handle data structures; classes inside service contain business logic, and so on. This separation makes large codebases navigable and maintainable.


2. Declaring a Package

The package statement goes on the very first line of a Java file, before anything else — before imports, before the class declaration.

package com.bookstore.model;

public class Book {
    private String title;
    private String author;

    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    public String getTitle() {
        return title;
    }
}

Rules for the package statement:

⚠️ A class with no package statement is in the default package. Avoid this in any project with more than a handful of classes — classes in the default package cannot be imported by classes in named packages.


3. Importing Classes

When you need to use a class from a different package, you bring it into scope with an import statement. Imports go after the package statement and before the class declaration.

package com.bookstore.service;

import com.bookstore.model.Book;   // import a specific class

public class BookService {

    public void printBook(Book book) {
        System.out.println(book.getTitle());
    }
}

Importing multiple classes from the same package

You can import them one by one, or use the wildcard * to import all public classes from a package at once:

// One by one — explicit, recommended
import com.bookstore.model.Book;
import com.bookstore.model.Author;

// Wildcard — imports everything in the package
import com.bookstore.model.*;

💡 Prefer explicit imports over wildcards. They make it immediately clear which classes a file depends on, and IDEs like IntelliJ will manage them for you automatically.

Classes you never need to import

The java.lang package — which contains everyday classes like String, Math, System, and Integer — is automatically imported by Java. That's why you've been using System.out.println() and String all along without any import statement.

// These are always available — no import needed
String name = "Alice";
System.out.println(Math.abs(-5));

Everything else — Scanner, Arrays, ArrayList, and so on — requires an explicit import:

import java.util.Scanner;
import java.util.Arrays;

4. Package Naming Conventions

Java uses a reverse domain name convention to guarantee globally unique package names. This matters when your code is shared as a library or used alongside third-party libraries.

Organisation Domain Package prefix
HackYourFuture hackyourfuture.net net.hackyourfuture
Google google.com com.google
Apache apache.org org.apache
Your project com.yourcompany.projectname

The full package name then adds sub-packages for the specific area of the codebase:

com.hackyourfuture.backend.model
com.hackyourfuture.backend.service
com.hackyourfuture.backend.util

Additional naming rules:

// ✅ Correct
package com.hackyourfuture.backend.model;

// ❌ Incorrect — uppercase, hyphen, wrong separator
package com.HackYourFuture.Back-End.Model;

💡 For learning projects where there's no real domain, it's common to use com.example or just your name: nl.yourname.projectname.


5. Packages and Directory Structure

This is where packages become concrete — the package name must exactly match the directory path of the file on disk. Java enforces this mapping; mismatches cause compile errors.

Given this package declaration:

package com.bookstore.model;

The file must live at this path:

src/
└── com/
    └── bookstore/
        └── model/
            └── Book.java       ← lives here

A typical project layout with multiple packages looks like this:

src/
└── com/
    └── bookstore/
        ├── model/
        │   ├── Book.java         → package com.bookstore.model
        │   └── Author.java       → package com.bookstore.model
        ├── service/
        │   └── BookService.java  → package com.bookstore.service
        └── util/
            └── PriceFormatter.java → package com.bookstore.util

🔍 In Node.js, the file path and the module path are the same thing — you require('./model/book') and the file is literally at that path. Java works the same way, except the package name in the source code must match the directory structure. Your IDE (IntelliJ) enforces and manages this for you automatically when you create new classes.

How IntelliJ handles this for you

When you right-click a package folder in IntelliJ and choose New → Java Class, it:

You rarely need to manage this manually — but understanding the underlying mapping is essential for reading error messages, navigating unfamiliar codebases, and working with build tools.


✏️ Exercises

Exercise 1 — Spot the Mistakes

The following project has three errors related to packages and imports. Identify each one.

File location: src/Model/Book.java

import java.util.Scanner;
package com.bookstore.model;

public class Book {
    private String title;
}

File location: src/com/bookstore/service/BookService.java

package com.bookstore.service;

public class BookService {
    public void display(Book book) {  // using Book from another package
        System.out.println(book);
    }
}

Exercise 2 — Create a Package Structure

Set up the following package structure in IntelliJ for a library management system: