Skip to content

Hello World — Class Declaration, main Method, and Compilation Process

DodaTech Updated 2026-06-28 7 min read

In this tutorial, you will learn about Hello World. We cover key concepts, practical examples, and best practices to help you master this topic.

The Hello World program in Java demonstrates class declaration, the main method signature, compilation to bytecode, and execution on the JVM. While the program is only five lines long, every keyword — public, class, static, void, main, String[], System.out.println — has a specific purpose that reveals how Java works under the hood.

What You'll Learn

  • The meaning of each keyword in a Java class declaration
  • Why the main method signature is fixed
  • The compilation and class-loading process
  • How System.out.println works

Why It Matters

Hello World is the smallest complete Java program. Understanding exactly what it does prepares you to debug compilation errors, understand public vs private access, and eventually design programs with multiple classes.

Real-World Use

Every Java developer writes and runs programs this way — whether in a local IDE, a CI pipeline, or an AWS Lambda. The same javac + java pattern underlies Maven, Gradle, and every build tool.


The Complete Program

public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

Save this as Hello.java, then:

javac Hello.java
java Hello

Expected output:

Hello, World!

Dissecting the Keywords

public class Hello

  • public — an access modifier that makes this class accessible from anywhere. If you omit public, the class has package-private visibility and is only accessible within its package.
  • class — a keyword that declares a class. Java is class-based; every piece of code lives inside a class.
  • Hello — the class name. By convention, class names are PascalCase. The file must be named Hello.java because Java requires the public class name to match the file name.

A class can have fields (variables), methods, constructors, and nested types. In this minimal program, the class contains only one method.

public static void main(String[] args)

This is the entry point of every standalone Java application. The JVM calls this method when you run java Hello.

  • public — the JVM needs unrestricted access to call this method. If it were private, the JVM could not invoke it.
  • static — the JVM calls main before any objects exist. A static method belongs to the class itself, not to instances.
  • void — the method returns nothing. Java programs exit by calling System.exit() or by reaching the end of main.
  • main — the method name the JVM looks for. Must be spelled exactly main.
  • String[] args — command-line arguments as an array of strings. Even if unused, this parameter is required. You can write String[] args or String... args (varargs).

System.out.println("Hello, World!");

  • System — a built-in Java class in the java.lang package, automatically imported.
  • System.out — a static field in System of type PrintStream, initialized by the JVM to the standard output stream (the terminal).
  • println — a method on PrintStream that prints the argument followed by a newline.
  • "Hello, World!" — a string literal enclosed in double quotes.

The Compilation Process

Source Code (.java) -> Lexical Analysis -> Parsing -> Semantic Analysis -> Bytecode Generation -> .class file
  1. Lexical Analysis: The compiler breaks the source into tokens — keywords (public, class), identifiers (Hello, main), separators ({, }), operators, and literals.
  2. Parsing: The tokens are arranged into an Abstract Syntax Tree (AST) that represents the program's structure according to the Java grammar.
  3. Semantic Analysis: The compiler checks types, resolves symbols, and verifies that code follows Java's rules (e.g., void methods cannot return a value).
  4. Bytecode Generation: The compiler produces .class files containing bytecode — platform-independent instructions for the JVM.

What Bytecode Looks Like

Use the javap tool to disassemble the bytecode:

javap -c Hello

Expected output:

Compiled from "Hello.java"
public class Hello {
  public Hello();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #13                 // String Hello, World!
       5: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

Each line is a JVM instruction. For example, getstatic #7 loads the System.out field, ldc #13 loads the string constant from the constant pool, and invokevirtual #15 calls the println method.

Class Loading and Execution

When you run java Hello:

  1. The Bootstrap class loader loads core JRE classes from rt.jar (or lib/modules in Java 9+).
  2. The system class loader loads Hello.class from the current directory (or classpath).
  3. The JVM verifies the bytecode for correctness and security violations.
  4. The JVM calls the main method. Execution begins.
  5. When main finishes, the JVM exits (unless there are non-daemon threads still running).

Common Mistakes

  1. Forgetting the String[] args parameter. The JVM will not recognize main() without it. You will get Main method not found in class Hello.
  2. Using string instead of String. Java is case-sensitive. String is the correct class; string will not compile.
  3. Writing main instead of main. A typo like mian compiles (as a regular method) but the JVM will not find the entry point.
  4. Naming the file differently from the class. class Hello must be in Hello.java, or you get a compilation error.
  5. Running java Hello.class instead of java Hello. The JVM expects a class name, not a file name. Append .class causes a load error.

Practice Questions

1. Why must the main method be public static void?
public so the JVM can access it, static so it can be called without an instance, and void because the program exits via System.exit() rather than a return value.

2. What is the difference between println and print?
println appends a newline after the output; print does not. So System.out.print("Hello"); System.out.print(" World") prints Hello World on one line.

3. What does the javap tool do?
It disassembles compiled .class files, showing the bytecode instructions, the constant pool, and method signatures.

4. What happens if you declare main as private?
The code compiles, but the JVM reports Main method not found in class Hello because it looks for a public method.

5. What is the purpose of the String[] args parameter?
It receives command-line arguments. For example, java Hello Alice Bob passes an array with ["Alice", "Bob"].

Challenge Question:
Write a Java program that prints all command-line arguments. Compile and run it with java ArgsDemo one two three. The output should list each argument on its own line. Use a for-each loop.

FAQ

Can I have multiple classes in one .java file?

Yes, but only one public class per file. Additional classes can have package-private visibility. This is useful for tightly coupled helper classes that should not be exposed externally.

What is the `javap -c` output telling me?

It shows the bytecode instructions for each method. The numbers (0, 1, 3, 5) are bytecode offsets. Instructions like getstatic and invokevirtual correspond to JVM operations. You do not need to memorize bytecode, but understanding it helps with debugging and performance tuning.

Why does `main` accept `String[] args` but some examples use `String... args`?

Both are valid. String... is varargs syntax introduced in Java 5. Inside the method, args is treated as an array. Using String... args is equivalent to String[] args.

What does the JVM do if `main` throws an exception?

If the exception propagates out of main, the JVM prints the stack trace to System.err and exits with a non-zero exit code. The default uncaught exception handler in the thread produces the stack trace output.

Why is there no `import` statement in Hello World?

The java.lang package is automatically imported by the compiler. Classes like String and System are in java.lang, so no explicit import is needed.

Mini Project

Create a program AboutMe.java that:

  1. Declares a class AboutMe with a main method
  2. Uses System.out.println to print your name, age, and favorite programming language on separate lines
  3. Uses System.out.print with \n to produce the same output
  4. Compiles both with and without the -g flag (debug info), and compare the sizes of the resulting .class files using ls -l or dir
  5. Run javap -c -p on the compiled class to see the default constructor and the main method bytecode

Reflect on why the compiler added a default constructor even though you did not write one.

What's Next

Now you understand the basic structure of a Java program. The next lesson introduces variables and data types — the eight primitive types, type conversion, type inference with var, and how default values work. This is where you start building programs that store and manipulate data.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro