algoz
Chapters/01 Java basics/How a Java program runs

How a Java program runs

Understand the structure of a program, the main method, and how statements execute.

Builds on
You'll gain
Know what every line doesfrom class structure to execution
Practice
Sheet coming sooncoding problems for this note
Summary

Every Java program lives inside a class, begins executing at the main method, and runs statements sequentially from top to bottom.

The idea in real life

Think of a recipe card in a kitchen. The card names the dish at the top, lists the steps in numbered order, and each step ends with a period before the next one starts. A Java program works like that card: the class names the program, main marks the first instruction, and the computer runs each statement from top to bottom until the list ends.

Why it exists

  1. Computers need an exact starting point and a clear sequence of steps to execute your instructions.
  2. Arranging code into classes, methods, and statements gives both the compiler and the programmer a consistent structure.
  3. Distinguishing syntax errors from runtime exceptions helps you diagnose and fix broken code quickly without guessing.
  4. Knowing how standard output works prepares you to trace algorithm state and inspect variables as you learn.

How it works

The parts of a program

Classes group code, while main marks where execution starts.

In Java, every line of runnable code lives inside a class. A class is a container that groups related data and instructions together. In this course, single-file programs use the container public class Main.

Inside the class sits a method. A method is a named block of code that performs a specific set of actions. The main method is special: it is the standard entry point where the Java Virtual Machine begins running your program.

Curly braces { and } define the boundaries of both classes and methods. The opening brace { marks where the container begins, and the closing brace } marks where it ends. Everything between those braces belongs to that container.

Inside main, you write statements. A statement is a complete instruction that commands the computer to perform an action. In Java, every statement must end with a semicolon ;. The semicolon tells the compiler that the current instruction is finished.

Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println("Line one");
        System.out.println("Line two");
    }
}
Output
Line one
Line two

In this program:

  • public class Main declares the outer container for the application.
  • public static void main(String[] args) declares the entry method where execution starts.
  • System.out.println("Line one"); is a statement that prints the characters Line one to the console and moves to the next line.
  • System.out.println("Line two"); is a second statement that prints Line two on the next line.

Printing

Use println to end a line, or print to keep writing.

Java provides two standard methods on System.out for printing text to the screen:

  • System.out.println: Prints the given text and automatically moves the cursor to the beginning of the next line (the ln stands for line).
  • System.out.print: Prints the given text and leaves the cursor directly after the last character printed. Any subsequent print call appends its output to the very same line.

When you want to include special characters inside text, such as a newline or a quotation mark, you use an escape sequence. An escape sequence begins with a backslash \ followed by a specific character code:

  • \n: Inserts a newline, advancing text to the next line.
  • \t: Inserts a horizontal tab, advancing text to the next tab stop for column alignment.
  • \": Inserts a literal double quote without ending the string literal.
  • \\: Inserts a single literal backslash.
Main.java
public class Main {
    public static void main(String[] args) {
        System.out.print("Algoz ");
        System.out.println("Course");
        System.out.println("Item:\t\"Notebook\"\nStatus:\tActive");
    }
}
Output
Algoz Course
Item:	"Notebook"
Status:	Active

In this program:

  • System.out.print("Algoz "); prints the word Algoz followed by a space, keeping the cursor on line 1.
  • System.out.println("Course"); appends Course right beside it and then moves down to line 2.
  • In the final statement, \t aligns the text into columns, \" prints literal quotes around Notebook, and \n starts the word Status: on line 3.

Statements run top to bottom

The computer runs each instruction in order, one line at a time.

A computer executes instructions in sequential order. Java reads the statements inside a method from the top line down to the bottom line, executing each statement completely before moving to the next.

Later notes introduce branches (if/else in note 6) and loops (note 7) that redirect or repeat instructions. Until you add those controls, execution flows in a strict, straight line.

Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println("Step 1: Check inputs");
        System.out.println("Step 2: Process data");
        System.out.println("Step 3: Print result");
    }
}
Output
Step 1: Check inputs
Step 2: Process data
Step 3: Print result

In this program:

  • The first statement prints Step 1: Check inputs.
  • Only after the first statement finishes does the computer execute the second statement, printing Step 2: Process data.
  • Finally, the third statement runs and prints Step 3: Print result.

Comments

Notes in your code explain reasons to people and are ignored by Java.

A comment is text written inside a source file for human readers. When javac compiles your code into bytecode, it completely discards all comments. Comments do not slow down execution and produce zero machine instructions.

Java supports three comment styles:

  • Single-line comment: Begins with two forward slashes // and extends to the end of the current line.
  • Multi-line comment: Begins with /* and ends with */. Everything between these markers is ignored, allowing comments to span multiple lines.
  • Documentation comment: Begins with /** and ends with */. This is a Javadoc comment, used by documentation tools to generate structured HTML references for libraries and APIs.

Use comments to explain why code exists or why a non-obvious choice was made, rather than repeating what the code plainly does.

Main.java
public class Main {
    public static void main(String[] args) {
        // Single-line comment: explain the why, not the obvious what
        System.out.println("Comments demo");

        /* Multi-line comment:
           useful for longer explanations
           spanning several lines. */
        System.out.println("Execution continues");
    }
}
Output
Comments demo
Execution continues

Going deeper

Blocks and indentation

Curly braces group statements together into a single unit of work.

A block in Java is a sequence of zero or more statements enclosed between matching curly braces { and }.

A block can appear anywhere a single statement is permitted. Blocks can also nest inside other blocks. The class body forms an outer block, the main method forms an inner block, and control structures (such as loops and conditional branches) introduce further nested blocks.

Java does not require indentation. The compiler reads tokens separated by whitespace and semicolon terminators, meaning a program written entirely on one line would compile identically to one formatted across dozens of lines.

However, formatting matters greatly to human readers, code reviewers, and interviewers. The standard convention in Java is 4 spaces of indentation for each level of nesting. Every statement inside a block is indented four spaces further than the enclosing braces. Consistent indentation makes the visual shape of your code reflect its logical hierarchy.

Names Java cares about

Identifier rules and conventions keep names valid, clear, and consistent.

An identifier is a name chosen by the programmer for a class, method, or variable. Java enforces specific syntactic rules regarding what names are legal:

  1. Case sensitivity: Java is strictly case-sensitive. The names main, Main, and MAIN represent three entirely distinct identifiers. Writing system.out.println produces a compile error because the standard library class is named System, not system.
  2. Valid characters: An identifier may contain letters (a–z, A–Z), digits (0–9), underscores (_), and currency symbols ($).
  3. Cannot start with a digit: score1 is a valid identifier, but 1score is illegal and rejected by the compiler.
  4. Cannot be a keyword: Java reserves over 50 keywords (such as class, public, static, void, int, and return). These words have dedicated meaning to the compiler and cannot be used as names for classes, methods, or variables.

Beyond syntax rules, the Java community follows widely accepted naming conventions:

  • Classes: PascalCase (also called UpperCamelCase), starting with a capital letter (for example, Main, ScoreTracker).
  • Methods and variables: camelCase (lowerCamelCase), starting with a lowercase letter and capitalizing each subsequent word (for example, calculateSum, itemCount).
  • Constants: UPPER_SNAKE_CASE, using all uppercase letters separated by underscores (for example, MAX_CAPACITY; final constants come in note 2).

Errors in your own code

Syntax mistakes stop the compiler; illegal actions fail while running.

As introduced in set up Java, programming errors fall into two stages: compile-time errors and runtime errors. When you write code, learning how to read the error message tells you exactly what went wrong and where.

Compile-time errors

A compile error occurs when source code breaks Java grammar or typing rules. When you run javac, the compiler halts without creating a .class bytecode file.

Consider this program with a missing semicolon on line 3:

CompileErrorDemo.java
public class CompileErrorDemo {
    public static void main(String[] args) {
        System.out.println("Hello")
    }
}

When compiled with javac CompileErrorDemo.java, the compiler reports:

text
CompileErrorDemo.java:3: error: ';' expected
        System.out.println("Hello")
                                   ^
1 error

The error report provides three vital pieces of information:

  • The file name and line number (CompileErrorDemo.java:3).
  • A description of what is missing (error: ';' expected).
  • A visual caret marker ^ pointing to the exact column where the compiler detected the missing punctuation.

Runtime errors

A runtime error occurs after compilation succeeds. The syntax is valid and bytecode was generated, but during execution the computer encounters an impossible or illegal operation. The JVM stops immediately and prints an exception.

Consider this program that attempts to read a command-line argument from args without checking whether one was provided:

RuntimeErrorDemo.java
public class RuntimeErrorDemo {
    public static void main(String[] args) {
        System.out.println(args[0]);
    }
}

When compiled, javac RuntimeErrorDemo.java produces RuntimeErrorDemo.class without complaint. But when executed with java RuntimeErrorDemo with no arguments, the JVM aborts:

text
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
	at RuntimeErrorDemo.main(RuntimeErrorDemo.java:3)

This stack trace identifies:

  • The thread where the failure occurred (thread "main").
  • The exception type (java.lang.ArrayIndexOutOfBoundsException).
  • The detailed reason (Index 0 out of bounds for length 0).
  • The method and source line where execution stopped (RuntimeErrorDemo.main(RuntimeErrorDemo.java:3)).

Under the hood

Why main looks the way it does

Four keywords give the JVM the exact entry point it needs.

The declaration public static void main(String[] args) looks verbose, but each keyword fulfills a necessary technical requirement:

  • public: An access modifier ensuring that the method is visible and callable by the JVM launcher from outside the class and package.
  • static: Allows the JVM to invoke the method directly on the Main class without instantiating an object on the heap first (chapter 02 explains static in full depth).
  • void: The return type indicating that the method returns no value to its caller when execution terminates.
  • String[] args: An array of text strings that captures any command-line arguments passed to the program when launched from a terminal.

When you pass words after the class name in your terminal, the JVM packages those words into an array of strings and delivers them to args. For example:

EchoArgs.java
public class EchoArgs {
    public static void main(String[] args) {
        System.out.println("Argument: " + args[0]);
    }
}

Running this file directly with java EchoArgs.java hello passes hello into index 0 of args:

text
Argument: hello

What System.out is

A ready-made print stream that directs text to standard console output.

The phrase System.out.println connects three distinct elements:

  • System: A built-in utility class in the java.lang package, which is automatically imported into every Java program.
  • out: A public static final field inside System holding a reference to a java.io.PrintStream object.
  • println: An instance method defined on PrintStream that formats data and writes characters to the output destination.

During JVM startup, the runtime initializes System.out and binds it to standard output (file descriptor 1 in operating systems).

System.out is created with automatic flushing turned on, so text you print is passed to the console straight away, even without a newline. That convenience has a cost: printing many small pieces one by one is slow. Note 12 and chapter 05 show faster ways to print a lot of output.

How the JVM finds main

The runtime looks up a public static main method before execution starts.

When you launch an application with java Main, the JVM performs a precise lookup procedure defined in the Java Virtual Machine Specification:

  1. The JVM loads and links the compiled bytecode for Main.
  2. It looks in the class for the entry method. The classic form, which works on every Java version, is public static void main(String[] args) (String... args is also accepted).
  3. If found, the JVM creates the primary execution thread named main and invokes the method.

Notice that the compiler does not require a class to have a main method. A file with utility functions or data classes compiles without error. However, if you instruct the runtime launcher java to execute a class lacking this exact entry point, the JVM halts immediately with an error:

text
Error: Main method not found in class Main, please define the main method as:
   public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application

If you misspell main as mian or change String[] to int[], the code still compiles, but the launcher stops with this error. On JDK 17, leaving out public or static gives the same error. Since JDK 25 (JEP 512) the launcher also accepts a shorter void main() with no public, static or args. This course always writes the classic form, because it works on every version and in every interview editor.

In Java

Main.java
public class Main {
    // Prints a decorated header for the execution report.
    static void printHeader() {
        System.out.println("================================");
        System.out.println("      ALGOZ EXECUTION REPORT    ");
        System.out.println("================================");
    }

    // Prints status entries using tabs and escape sequences.
    static void printDetails() {
        System.out.print("Module:\t\t");
        System.out.println("01-java-basics");
        System.out.print("Program:\t");
        System.out.println("\"how-java-runs\"");
        System.out.println("Status:\t\tReady\nExit Code:\t0");
    }

    public static void main(String[] args) {
        printHeader();
        printDetails();
        System.out.println("--------------------------------");
        System.out.println("Report complete.");
    }
}
Output
================================
      ALGOZ EXECUTION REPORT    
================================
Module:		01-java-basics
Program:	"how-java-runs"
Status:		Ready
Exit Code:	0
--------------------------------
Report complete.

Traps

  1. Missing semicolon at the end of a statement

    In Java, every statement must terminate with a semicolon ;. Omitting the semicolon prevents compilation with the message error: ';' expected.

    ✕ WRONGSystem.out.println("Hello")
    ✓ RIGHTSystem.out.println("Hello");
  2. Wrong capitalisation for standard classes or keywords

    Java is strictly case-sensitive. The standard output stream is System.out with an uppercase S. Writing system.out causes the compiler to search for a package or variable named system, resulting in error: package system does not exist.

    ✕ WRONGsystem.out.println("Hello");
    ✓ RIGHTSystem.out.println("Hello");
  3. Misspelling main or altering its entry signature

    The launcher looks for a method named exactly main, in lowercase. If the name is misspelled, the file compiles cleanly but the launcher stops with Error: Main method not found in class.

    ✕ WRONGpublic static void mian(String[] args)
    ✓ RIGHTpublic static void main(String[] args)
  4. Assuming print adds a trailing newline

    System.out.print leaves the cursor immediately following the printed characters. The next print operation will attach its output to the same line. Use System.out.println whenever subsequent output should start on a fresh line.

    ✕ WRONGSystem.out.print("Step 1");
    ✓ RIGHTSystem.out.println("Step 1");
  5. Unclosed string literal or mismatched curly brace

    String literals must open and close with double quotes on the same line. Missing a closing quote produces unclosed string literal. Similarly, every opening brace { requires a matching closing brace }, otherwise the compiler reports reached end of file while parsing.

    ✕ WRONGSystem.out.println("Hello);
    ✓ RIGHTSystem.out.println("Hello");
  6. Forgetting to escape quotation marks inside strings

    A double quote inside a string literal tells the compiler that the string has finished. To print literal quotation marks, prefix each inner quote with a backslash (\").

    ✕ WRONGSystem.out.println("Name: "Algoz"");
    ✓ RIGHTSystem.out.println("Name: \"Algoz\"");
AlgozSet in Geist & Geist MonoJava track