Web Analytics

Code Organization

Advanced ~35 min read

Well-organized code is essential for maintainable and scalable Java applications. Packages help organize related classes into logical groups, making code easier to navigate, understand, and reuse. In this lesson, you'll learn about packages, import statements, package naming conventions, access modifiers in the context of packages, and how to distribute code using JAR files.

What are Packages?

A package is a namespace that organizes related classes and interfaces. It's similar to folders on your computerโ€”packages help organize your code and prevent naming conflicts.

Benefits of Packages

  • Organization: Group related classes together
  • Namespace: Prevent naming conflicts (two classes can have the same name in different packages)
  • Access Control: Package-private access allows classes in the same package to access each other
  • Reusability: Easier to share and reuse code across projects

Package Declaration

Package declaration must be the first non-comment statement in a Java file:

Output
Click Run to execute your code

Package Naming Conventions

Java follows a reverse domain name convention for package naming to ensure uniqueness:

// Use reverse domain name
package com.example.util;        // com.example is the domain
package org.apache.commons.io;   // org.apache is the domain
package net.mycompany.tools;     // net.mycompany is the domain

// All lowercase
package com.mycompany.MyPackage;  // Wrong - uppercase
package com.mycompany.mypackage;  // Correct

// Use singular nouns
package com.example.utilities;    // Acceptable
package com.example.util;         // Better - shorter, clearer

Package Naming Rules

  • Use reverse domain name (e.g., com.company.project)
  • All lowercase letters
  • No underscores or hyphens (use camelCase if needed)
  • Use meaningful, short names
  • Package name should match directory structure

Import Statements

Import statements tell Java which classes from other packages you want to use. They appear after the package declaration and before the class declaration.

package com.example.app;

// Import specific class
import java.util.ArrayList;
import java.util.List;

// Import all classes from a package (not recommended)
import java.util.*;

// Static import (for static members)
import static java.lang.Math.PI;
import static java.lang.Math.pow;

// Using fully qualified name (no import needed)
java.util.Date date = new java.util.Date();

Avoid Wildcard Imports

Using import java.util.*; imports all classes from that package, which can lead to naming conflicts. It's better to import specific classes you need.

Access Modifiers with Packages

Access modifiers control visibility of classes, methods, and variables. In the context of packages:

Modifier Same Class Same Package Subclass (Different Package) Different Package
private โœ“ โœ— โœ— โœ—
default (package-private) โœ“ โœ“ โœ— โœ—
protected โœ“ โœ“ โœ“ โœ—
public โœ“ โœ“ โœ“ โœ“
package com.example.util;

public class UtilClass {
    private int privateVar;      // Only accessible within this class
    int packageVar;              // Accessible within same package
    protected int protectedVar;  // Accessible in same package and subclasses
    public int publicVar;        // Accessible everywhere
}

JAR Files

A JAR (Java Archive) file is a package format used to aggregate many Java class files and associated metadata into a single file for distribution.

Output
Click Run to execute your code

Creating a JAR File

To create a JAR file from compiled classes:

# Compile Java files
javac -d . Calculator.java

# Create JAR file
jar cvf calculator.jar com/example/library/

# View contents of JAR
jar tf calculator.jar

# Extract JAR contents
jar xf calculator.jar

JAR File Commands

  • c - Create archive
  • v - Verbose output
  • f - Specify filename
  • t - List table of contents
  • x - Extract files

Package Directory Structure

Package names must match the directory structure. For a package com.example.util, the directory structure should be:

project-root/
โ””โ”€โ”€ src/
    โ””โ”€โ”€ com/
        โ””โ”€โ”€ example/
            โ””โ”€โ”€ util/
                โ””โ”€โ”€ UtilClass.java

The fully qualified name of UtilClass would be com.example.util.UtilClass.

Common Mistakes

1. Package name doesn't match directory structure

// File is at: src/com/example/MyClass.java
// But package declaration is:
package com.example.util;  // Wrong! Directory doesn't match

// Correct:
package com.example;

2. Using uppercase in package names

// Wrong
package com.example.MyPackage;
package com.example.my_package;

// Correct
package com.example.mypackage;
package com.example.util;

3. Missing package declaration

// Wrong - class in default package
// No package declaration
public class MyClass {
    // ...
}

// Correct - explicit package
package com.example;
public class MyClass {
    // ...
}

4. Import conflicts

// Wrong - ambiguous imports
import java.util.Date;
import java.sql.Date;  // Error! Both have Date class

// Correct - use fully qualified name
import java.util.Date;
java.sql.Date sqlDate = new java.sql.Date(...);

Exercise: Create a Package Structure

Task: Create a package structure for a library management system:

  • Create package com.mylibrary.model with a Book class
  • Create package com.mylibrary.service with a BookService class
  • Import and use the Book class in BookService
  • Use appropriate access modifiers
Output
Click Run to execute your code
Show Solution
// Book.java in com.mylibrary.model package
package com.mylibrary.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; }
    public String getAuthor() { return author; }
}

// BookService.java in com.mylibrary.service package
package com.mylibrary.service;
import com.mylibrary.model.Book;

public class BookService {
    public void displayBook(Book book) {
        System.out.println("Title: " + book.getTitle());
        System.out.println("Author: " + book.getAuthor());
    }
}

Summary

  • Packages organize related classes and prevent naming conflicts
  • Package names use reverse domain convention (e.g., com.example.util)
  • Package names must be lowercase and match directory structure
  • Import statements allow using classes from other packages
  • Access modifiers control visibility across packages
  • Default (package-private) access allows same-package access
  • JAR files package compiled classes for distribution
  • Use specific imports instead of wildcard imports when possible

What's Next?

Now that you understand code organization, the next lesson covers Unit Testing with JUnit, which shows you how to write and run automated tests for your Java code.