Code Organization
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:
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.
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 archivev- Verbose outputf- Specify filenamet- List table of contentsx- 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.modelwith aBookclass - Create package
com.mylibrary.servicewith aBookServiceclass - Import and use the
Bookclass inBookService - Use appropriate access modifiers
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.
Enjoying these tutorials?