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.

<aside> 💭

Coming from JavaScript and Node.js, you're used to organising code into separate files and folders, then connecting them with import. 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.

</aside>

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:

<aside> ⚠️

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.

</aside>


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.*;

<aside> 💡

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.

</aside>

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;

<aside> 💡

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

</aside>


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

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:

com.library
├── model    → create a class: Book (fields: title, author, isbn)
├── service  → create a class: LibraryService (one method: printBook(Book book))
└── util     → create a class: InputHelper (a Scanner wrapper with one method: readLine())