Java Structure: Main Class, Packages, Imports
The Problem
Imagine you're joining a team. You walk into the office. There are files everywhere. No folders. No organization. Nobody knows where anything is. Finding what you need takes hours.
That's what unstructured Java code looks like.
Professional Java code isn't just about functionality. It's about organization. It's about making your code easy to find, easy to understand, and easy to modify.
This section teaches you the conventions that professional Java developers use. These aren't suggestions. They're standards that every Java developer on Earth follows.
Advanced Concepts:
While reading this section, you'll find some advanced concepts like public, static, void, and access modifiers. Don't worry, these concepts belong to Object-Oriented Programming (OOP), which is our next chapter.
We included them here on purpose. You need to understand the basics of how Java files are structured and how the main method works to run your code. But the why and the deeper mechanics of these keywords will be super clear Inshallah when we dive into OOP.
For now, just accept them as "the way Java works." Master the details later. Programming knowledge builds in layers.
The Anatomy of a Java File
Let's look at a basic Java file and understand each part:
package com.mycompany.calculator; // Package declaration (line 1)
import java.util.Scanner; // Imports (line 3)
import java.io.FileWriter;
public class Calculator { // Class declaration (line 6)
public static void main(String[] args) { // Main method (line 8)
System.out.println("Hello, World!");
}
}Don't worry! We'll explain every single word and concept in this code in upcoming chapters. For now, just focus on understanding the overall structure.
Every Java file has this structure:
1. Package declaration (optional, but professional code has it)
2. Import statements (only what you need)
3. Class declaration
4. Class body (variables, methods)The Equation: Package first -> then imports -> then code. Always in this order.
Let's understand each part.
Note: This section focuses on classes, packages, and imports, the basics of Java structure. Java also has a larger-level system called modules, introduced in Java 9. A module is like a “package of packages,” used to group big parts of an application and explicitly control what code is exposed or hidden.
The Main Method: The Entry Point
Every Java program needs an entry point. This is where execution starts.
That entry point is the main method:
public static void main(String[] args) {
// Your code runs here
}When you run your program using the class name (e.g., java Calculator), the Java Virtual Machine (JVM) looks for this exact method signature (public static void main(String[] args)) inside that class and immediately starts executing the program from the code within it.
Why this exact signature?
public static void main(String[] args)For now, don't worry about all the keywords here.
This is simply the standard method the JVM looks for when starting your program.
We'll explain public, static, and what the rest actually mean later in the Object Oriented Programming (OOP) chapter, where it will make much more sense.
Can a program have multiple main methods?
Technically yes, but only one is the entry point (the one in the class you're running).
Real example:
public class MyApp {
public static void main(String[] args) {
System.out.println("This runs when you type: java MyApp");
}
}
public class TestApp {
public static void main(String[] args) {
System.out.println("This runs when you type: java TestApp");
}
}Both have main methods, but which runs? Whichever one you specify:
java MyApp-> runs MyApp's mainjava TestApp-> runs TestApp's main
Important rule: Only one public class per file. If you want multiple classes in one file, only one can be public.
// Same file
public class MyApp {
public static void main(String[] args) {
// ...
}
}
class HelperClass { // Not public
// Helper code
}Packages: Organizing Your Code
A package is like a folder for your Java classes.
Why packages?
Imagine you have 500 Java files. No packages. Finding anything is a nightmare.
Packages organize related code:
com/
├── nzarcompany/
│ ├── calculator/
│ │ ├── Calculator.java
│ │ ├── Operation.java
│ │ └── Result.java
│ ├── database/
│ │ ├── Connection.java
│ │ └── Query.java
│ └── utils/
│ ├── Logger.java
│ └── Validator.javaThis structure prevents file naming conflicts and makes the code discoverable.
When to Use Packages?
- 1 to 2 files -> Optional, but good to practice with packages
- 3 or more files -> Always use packages
- Production code -> Always use packages (non-negotiable)
You should use packages when:
-
Your project has multiple files: Even with just 5-10 files, packages keep things organized
-
Working in a team: Prevents naming conflicts and makes code discoverable
- Your team can quickly find the "user authentication" code in
com.mycompany.auth - Another team's code won't conflict with yours
- Your team can quickly find the "user authentication" code in
-
You want to separate concerns: Different packages for different functionality
-
You're building professional code: Every production Java project uses packages
You can skip packages when:
- Learning beginner concepts: Your first "Hello, World" program
- Writing quick scripts or prototypes: Writing code you'll delete tomorrow
- Single-file utility - A tiny one-off tool that's just practice
But honestly: Once you're past "Hello, World," use packages. It's a good habit. Even for learning projects.
How to Name Packages?
Package names follow a specific rule:
reverse domain name + project name + module nameExample:
Your company owns nzarcompany.com. You're building a calculator:
Package name: com.nzarcompany.calculatorAnother company owns acme.org. They're building authentication:
Package name: org.acme.authThe reverse domain is intentional. It prevents naming conflicts across companies. Two companies can both have a calculator package, but com.mycompany.calculator and com.acme.calculator are different.
Rules:
- Always lowercase
- Separated by dots
- Start with reverse domain
- As specific as needed
Declaring a Package
At the top of every Java file, declare its package:
package com.nzarcompany.calculator;
public class Calculator {
// ...
}File system requirement:
Your file must be in the correct folder structure:
src/
├── com/
│ └── nzarcompany/
│ └── calculator/
│ └── Calculator.javaIf your package is com.nzarcompany.calculator, your file must be in com/nzarcompany/calculator/.
The package structure must match the folder structure. This is not optional.
Why? When you run java com.nzarcompany.calculator.Calculator, the JVM looks for:
- Folder:
com/nzarcompany/calculator/ - File:
Calculator.java
If the folder structure doesn't match the package name, the JVM can't find your file.
Imports: Using Other Packages
Once you organize code into separate packages (folders), you use imports to bring in and use the classes from those other packages.
That's where import comes in.
Without imports (fully qualified name):
package com.nzarcompany.calculator;
public class Calculator {
public static void main(String[] args) {
java.util.Scanner scanner = new java.util.Scanner(System.in);
java.io.FileWriter writer = new java.io.FileWriter("output.txt");
}
}This works, but it's too long. java.util.Scanner is the fully qualified name (full path to the class).
With imports (simpler):
package com.nzarcompany.calculator;
import java.util.Scanner;
import java.io.FileWriter;
public class Calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
FileWriter writer = new FileWriter("output.txt");
}
}Much cleaner. You import what you need, then use the short name.
Import Rules
Rule 1: Import specific classes
import java.util.Scanner; // Good: specific
import java.util.ArrayList; // Good: specificRule 2: Don't use * imports in real projects
import java.util.*; // Bad: imports everythingUsing * looks easy, but it's not a good habit because:
- You can't see which classes are actually used
- Different classes can have the same name and cause problems
- It can slow the compiler a little
- It makes the code harder to understand
In professional code, always import the exact classes you need.
Rule 3: Only import what you use
import java.util.Scanner;
import java.io.FileWriter;
import java.time.LocalDate;
import java.math.BigDecimal;
public class Calculator {
// Only uses Scanner and FileWriter
// Remove the other imports
}Unused imports just make your code messy. Most code editors will warn you when you have them.
Common Java Imports
You'll see these constantly:
import java.util.ArrayList; // Lists
import java.util.HashMap; // Maps/dictionaries
import java.util.Scanner; // User input
import java.io.FileWriter; // File writing
import java.io.BufferedReader; // File reading
import java.time.LocalDate; // DatesImporting Your Own Classes
You can import classes from other packages in your own project:
package com.myapp.calculator;
import com.myapp.tools.MathHelper;
import com.myapp.tools.Printer;
public class Calculator {
// Uses MathHelper and Printer from other packages
}Complete Code Example
Let's build a small, easy-to-understand project structure using the simple class names we picked earlier.
Project structure:
src/
└── com/
└── myapp/
├── calculator/
│ ├── Calculator.java
│ └── MathHelper.java
└── tools/
└── Printer.javaFile 1: Printer.java (utility class)
package com.myapp.tools;
public class Printer {
public static void print(String message) {
System.out.println("[PRINT] " + message);
}
}File 2: MathHelper.java (helper class)
package com.myapp.calculator;
public class MathHelper {
public static int add(int a, int b) {
return a + b;
}
public static int subtract(int a, int b) {
return a - b;
}
}File 3: Calculator.java (main class with entry point)
package com.myapp.calculator;
import com.myapp.tools.Printer;
public class Calculator {
public static void main(String[] args) {
Printer.print("Calculator started");
int result = MathHelper.add(5, 3);
Printer.print("5 + 3 = " + result);
result = MathHelper.subtract(10, 4);
Printer.print("10 - 4 = " + result);
}
}Note: We don't need to import MathHelper inside Calculator because both classes are in the same package (com.myapp.calculator). Java automatically makes all classes within the same package visible to each other. We only need to use import when the class we want to use is located in a different package, like Printer in com.myapp.tools.
How to run it:
# From the src/ directory
java com.myapp.calculator.CalculatorOutput:
[PRINT] Calculator started
[PRINT] 5 + 3 = 8
[PRINT] 10 - 4 = 6What happened:
- The JVM looks for:
com/myapp/calculator/Calculator.class - It finds the
mainmethod and starts running your program Calculatorimports and usesPrinterfrom another packageCalculatoralso callsMathHelpermethods from the same package- Program runs successfully
Access Modifiers
When you write a class or method, you control who can access it:
public class Calculator { // Anyone can use this
public static void add() {} // Anyone can call this
private static void helper() {} // Only this class can use
}The access modifiers:
| Modifier | Within Class | Same Package | Other Packages | Everyone |
|---|---|---|---|---|
public | ✓ | ✓ | ✓ | ✓ |
protected | ✓ | ✓ | ✓ (if inherited) | ✗ |
| (default) | ✓ | ✓ | ✗ | ✗ |
private | ✓ | ✗ | ✗ | ✗ |
For now, remember:
- public -> Available to everyone (use for public methods)
- private -> Only within this class (use for helper methods)
- (default, no modifier) - Only within this package (rarely used)
Best Practices for Java Structure
1. One public class per file
// Good: One public class per file
public class Calculator {
// ...
}// Bad: Multiple public classes in one file
public class Calculator { }
public class Operation { }Because Java requires each public class to have its own file with the same name, which makes projects easier to organize, read, and maintain.
2. Class name matches filename
Calculator.java contains class Calculator
Operation.java contains class Operation
Logger.java contains class LoggerIf the class name doesn't match the filename, the Java compiler will throw an error. For example, if Calculator.java contains public class Operation, the compiler won't know which file to associate with the class, and your program won't compile.
3. Organize packages by functionality
com.myapp.
├── calculator/ // All calculator-related
├── database/ // All database-related
├── authentication/ // All auth-related
└── utils/ // Shared utilities4. Keep packages focused
One package should have related classes. Don't mix calculator code with authentication code.
5. Use meaningful names
com.myapp.calculator // Clear
com.myapp.calc // Not Clear
Database.java // Clear
DB.java // Not Clear6. Avoid deep nesting
- Good:
com.myapp.calculator - Bad:
com.myapp.calculator.arithmetic.operations.advanced
Keep it short. 2 to 4 levels is typical.
Common Mistakes
Mistake 1: Package declaration mismatch
// File: src/com/myapp/calculator/Calculator.java
package com.myapp.calc; // WRONG! Should be com.myapp.calculator
public class Calculator {
// ...
}The JVM looks for this file in com/myapp/calc/ folder. It won't find it.
Mistake 2: Forgetting the main method signature
public static void main() { // WRONG! Missing String[] args
// ...
}The JVM specifically looks for main(String[] args). If you're missing the parameter, the JVM won't recognize it as the entry point.
Why This Matters
-
For reading code: Professional Java code follows these conventions. Understanding them means you can navigate any Java project.
-
For writing code: When you write code that others will read, structure matters. Poor organization frustrates teammates.
-
For scaling: As projects grow (thousands of files), good structure keeps things manageable. Bad structure collapses.
-
For interviews: Interviewers will ask about packages, imports, and the main method. Knowing these shows you understand Java fundamentals.
-
For real projects: Every company follows these conventions. Learning them now means you can jump into professional codebases immediately.
In Summary
Java structure is organized using a proven pattern:
- Package declaration: Organizes code into logical groups
- Imports: Lets you use classes from other packages
- Main method: Entry point for your program
- Access modifiers: Control who can access what
- File organization: Code files match package structure
Following these conventions makes code:
Easy to find, easy to understand, easy to modify and professional.
Master these fundamentals. They're the foundation for everything else in Java.
Next up: Mastering Data Types & Variables.