AlgoInsight

Free lesson · Java Basic To Advance

First Program

Easy6 min readjava

Hello, World — But Properly

Every programming course has a "Hello, World" Topic. Most of them just show the canonical example and move on. We're going to do more — write Hello World, then explain every single part of it, then write a few variations, then run it from the command line and trace what actually happens.

By the end of this Topic, you'll have written and run real Java code, and you'll understand why the code looks the way it does.

The Canonical Hello World

The classic Java Hello World:

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

That's seven words of actual output ("Hello, world!") wrapped in 80+ characters of ceremony. Java is famously verbose for tiny programs. Let me walk through every part.

public class HelloWorld — declares a class named HelloWorld. The public access modifier means this class is visible from anywhere. Java requires all top-level code to be inside a class (with one exception we'll mention shortly).

public static void main(String[] args) — the entry point of the program. The JVM looks for a method matching this exact signature when you run a Java class. Each word matters:

If you misspell main, leave off static, change the return type, or use any other parameter signature, the JVM won't find an entry point and refuses to run.

System.out.println("Hello, world!"); — prints a string to standard output, followed by a newline. Breaking this down:

Java statements end with semicolons. That's required, not optional.

The braces. Java uses { and } to delimit blocks — classes, methods, loops, conditionals. Convention puts the opening brace at the end of the line that starts the block, not on its own line (Java convention differs from C# convention here).

Interactive animation: Why main is static - otherwise the JVM would need an instance, a constructor, and arguments it cannot know.

Running the Program

Save the code above to a file named HelloWorld.java. The file name must match the public class name. Java is strict about this.

From the command line:

# Compile
javac HelloWorld.java

# Run
java HelloWorld

You should see Hello, world! printed.

What just happened:

  1. javac HelloWorld.java invoked the Java compiler, which read the source and produced HelloWorld.class — the bytecode
  2. java HelloWorld invoked the JVM, which loaded HelloWorld.class, found the main method, and executed it
  3. main called System.out.println, which output the string

Note that the java command takes a class name (no .class extension), not a file name. The JVM searches the classpath for a file matching that class name.

graph LR
    A[HelloWorld.java<br/>source code] -->|javac| B[HelloWorld.class<br/>bytecode]
    B -->|java| C[JVM loads class]
    C --> D[JVM finds main method]
    D --> E[JVM executes bytecode]
    E --> F["Hello, world!"<br/>printed to stdout]

    style A fill:#7c3aed,color:#fff
    style B fill:#10b981,color:#fff
    style E fill:#3b82f6,color:#fff
    style F fill:#f59e0b,color:#fff
This diagram shows the compile-and-run cycle for a Java program. You start with HelloWorld.java, a source file. The javac compiler reads it and produces HelloWorld.class, a bytecode file. When you run java HelloWorld, the JVM loads that class file into memory. The JVM looks for a method named main with the specific signature taking a String array. It then executes the bytecode for that method, which calls System.out.println, which writes "Hello, world!" to standard output. This is the cycle for every Java program, however complex.

Modern Java: Hello World, Shorter

Java 21 introduced "unnamed classes and instance main methods" (technically still in preview in some versions). This lets you write:

void main() {
    System.out.println("Hello, world!");
}

No public class wrapper. No static. No String[] args parameter. Just the method.

To run with this syntax (Java 21+):

java --enable-preview --source 21 HelloWorld.java

This feature is aimed at beginners and competitive programming. Production code still uses the explicit class syntax. We mention it because (1) it answers the "why is Hello World so verbose?" complaint, and (2) interviewers occasionally ask about recent language features.

Interactive animation: The classic HelloWorld beside the Java 21 version - no public class wrapper, no static, no String[] args.

Variations to Internalize

Let me show a few small variations on Hello World that build understanding.

Echoing command-line arguments:

public class Echo {
    public static void main(String[] args) {
        for (String arg : args) {
            System.out.println(arg);
        }
    }
}

Run with: java Echo hello world from command line. Each argument prints on its own line.

Reading from standard input:

import java.util.Scanner;

public class Greet {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("What's your name? ");
        String name = scanner.nextLine();
        System.out.println("Hello, " + name + "!");
        scanner.close();
    }
}

This demonstrates the import statement (covered in detail in Module 12), Scanner for input, and string concatenation with +.

Using printf for formatted output:

public class Format {
    public static void main(String[] args) {
        String name = "Olena";
        int age = 35;
        double height = 1.68;

        System.out.printf("Name: %s, Age: %d, Height: %.2f%n", name, age, height);
    }
}

%s is a string placeholder, %d is an integer, %.2f is a float with 2 decimal places, %n is a platform-appropriate newline. Java's format specifiers come from C's printf.

What javac Produces

A small experiment to understand what compilation actually produces. Compile HelloWorld.java and then inspect the result:

javac HelloWorld.java
javap -c HelloWorld

javap -c disassembles the class file, showing the bytecode in human-readable form. You'll see something like:

Compiled from "HelloWorld.java"
public class HelloWorld {
  public HelloWorld();
    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
}

This is the bytecode that the JVM actually executes. The numbers in the left column are bytecode offsets. Each opcode (aload_0, invokespecial, getstatic) is a JVM instruction. The #N references are pointers into the constant pool (constants and references stored in the class file).

You don't need to read or write bytecode in practice — javac handles compilation. But seeing bytecode at least once makes the abstract "compiles to bytecode" claim concrete.

Common Pitfalls

Warning: File name doesn't match public class name. Java requires public class HelloWorld to be in a file named HelloWorld.java. Mismatches produce errors like "class HelloWorld is public, should be declared in a file named HelloWorld.java."

Forgetting static on main. A non-static main won't be found by the JVM. The error is "Main method not found in class HelloWorld."

Misspelling main. Main, MAIN, main() (without String[] args) — none of these work. The JVM looks for the exact signature public static void main(String[] args).

Missing semicolons. Every statement must end with one. Java will not silently forgive you.

Running java HelloWorld.class. You run with the class name, not the file name. Use java HelloWorld.

Running from the wrong directory. The class file needs to be in your current directory or on the classpath. If you compile in one directory and try to run from another, the JVM won't find the class.

Interactive animation: Six first-program errors and what Java says for each - learn the message, not just the mistake.

Why This Matters in Interviews

Interview: First-program-style questions don't appear in senior interviews, but the parts of Hello World — class structure, the main signature, System.out.println — are foundational vocabulary that everything builds on. Senior interviews assume you can write this fluently and probe deeper material.

What does come up: occasionally, interviewers ask "why is main static?" The answer: because the JVM needs to invoke it without first creating an instance of the class. If main weren't static, the JVM would need to create an instance, which would require a constructor, which raises questions about which constructor to call and with what arguments. Making main static sidesteps all of that.

Try It

Exercise: Write and run all three example programs from this Topic:

  1. HelloWorld.java — the canonical version
  2. Echo.java — echoes command-line arguments
  3. Greet.java — reads input and greets the user

For each program:

  • Compile with javac
  • Run from the command line
  • Run javap -c <ClassName> to see the bytecode

Then try the modern variant — if you have Java 21+, write the unnamed-class version of HelloWorld and run it with --source 21. Compare the bytecode it produces (javap -c HelloWorld) to the original. You'll see the JVM still treats it as a class under the hood.

Don't skip the bytecode step. Seeing what javac produces makes the abstract "compiles to bytecode" claim concrete in a way no diagram can match.

Back to Java Basic To Advance