Module 1 · Getting Started & Mental Models ⏱ 19 min

Your First Java Program (main, println)

By the end of this lesson you will be able to:
  • Write the minimum valid Java program: a public class whose file name matches, with an exact main signature
  • Explain what each keyword in public static void main(String[] args) is for, and why omitting one stops the program starting
  • Print output with println and print, join values with +, and avoid its left-to-right trap

Every Java program looks far heavier than the task it performs. Where Python prints a greeting with a single short line and stops, Java wraps that one action inside a class, a method, and an exact signature before it will lift a finger. That ceremony is the most common reason newcomers walk away from the language in their first week.

The move that changes everything is to stop reading the boilerplate as noise. Each layer exists because Java was designed for programs that swell into hundreds of files and run for a decade, and at that scale the structure that feels absurd at five lines is exactly what keeps a sprawling codebase readable. Nothing here is decoration. This lesson names every piece of the outline, so that by the end the shape is automatic and the error messages you meet next start to read in plain English.

flowchart TD
  CLASS["public class Main"] --> METH["public static void main(String[] args)"]
  METH --> ST1["System.out.println(...);"]
  METH --> ST2["System.out.println(...);"]
  style CLASS fill:#c2410c,color:#fff
  style METH fill:#c2410c,color:#fff
The structure of a minimal Java program: class wraps method wraps statements.

Anatomy of a minimal program

Here is the smallest Java program that produces visible output, with each part named:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, world");
    }
}
  • public class Main declares a class called Main. By Java's rule, the file must be named Main.java, because the public class and its file share a name.
  • public static void main(String[] args) is the entry point. The JVM looks for this exact signature and starts running from there.
  • System.out.println("...") writes one line to the console and then moves down to the next line.
  • A semicolon ends every statement; drop one and the compiler stops, usually flagging the line after the real mistake.
  • Braces group a block: the class body holds the method, and the method body holds its statements.

Reading what the compiler tells you

When compilation fails, the compiler prints a file name and a line number, but it often points one line below the real mistake. It only realises a statement is unfinished when the next one begins, so a missing semicolon on line 4 is reported at line 5. Read the message, then look up a line.

You can also leave notes for yourself with //, which begins a comment: everything from there to the end of the line is ignored by the compiler. Comments explain intent to the next reader, who is very often you, three months later.

What every word of main is for

That signature looks arbitrary; it is not. Each keyword earns its place, and knowing them turns cryptic launch errors into obvious ones.

  • public lets the JVM reach this method from outside the class. Make it private and the file compiles, but nothing can start it.
  • static means the method belongs to the class itself, so the JVM can invoke it before any object exists. Without static, Java would need an object to run main first, and at launch no object exists yet.
  • void declares that the method returns nothing; it simply runs.
  • main is the exact name the JVM searches for. Rename it to start and the code compiles, then sits dead.
  • String[] args collects the command-line arguments as an array of text. A program can ignore them, but it cannot drop the parameter.

Change any one and the file still compiles, but fails at launch: the JVM cannot find a usable entry point.

flowchart TD
  J["JVM loads Main.class"] --> S["Looks for one exact method:<br/>public static void main(String[] args)"]
  S -->|found| R["Starts here, runs the first statement"]
  S -->|not found| E["Refuses to start:<br/>no usable main method"]
  style R fill:#3776ab,color:#fff
  style E fill:#b45309,color:#fff
Execution begins only if the JVM finds that one exact signature. Rename the method, drop static, or change the parameter, and the file still compiles but the program never starts.

Braces define blocks; whitespace does not

If you are coming from Python, this is the rule that will save you the most confusion. Python uses indentation to decide which lines belong together; Java uses braces and ignores indentation entirely. You could flatten the whole program onto one line and it would still compile, because the compiler tracks braces, not spaces.

Indentation in Java exists purely for the human reading it. The universal convention is four spaces per nested level, matching how deep the braces sit, so the eye can see the structure at a glance. The compiler does not enforce that convention; other programmers do.

Main.java — a program that prints four lines. Real, compiling Java.
public class Main {
    public static void main(String[] args) {
        String language = "Java";
        int version = 21;
        System.out.println("Language: " + language);
        System.out.println("Version: " + version);
        System.out.println("Ready to learn.");
        System.out.println("Let's begin.");
    }
}

Printing with println and print

System.out.println writes its argument and then advances to a fresh line; System.out.print writes the same text and stays put, so the next call continues exactly where this one ended. Reach for println when each value deserves its own line, and for print when you want to assemble one line from several pieces.

Both accept a string, a number, or several values joined with +. When + has text on one side, Java converts the other side to text and stitches them together, so "Version: " + 21 prints Version: 21. That stitching is called concatenation, and it is convenient enough to hide a trap you will meet shortly.

flowchart TD
  P["System.out.print(x)"] --> PO["writes x, then stays on this line"]
  L["System.out.println(x)"] --> LO["writes x, then drops to the next line"]
  style PO fill:#b45309,color:#fff
  style LO fill:#3776ab,color:#fff
print writes text and leaves the cursor where it is; println writes text and then advances to a new line.
Main.java — print builds a line in pieces; println ends it. Real, compiling Java.
public class Main {
    public static void main(String[] args) {
        System.out.print("Hello");
        System.out.print(", ");
        System.out.println("world");
        System.out.println("Line two");
    }
}
Exercise

What does this program print? Read it carefully and type the exact output (four lines).

public class Main {
    public static void main(String[] args) {
        String language = "Java";
        int version = 21;
        System.out.println("Language: " + language);
        System.out.println("Version: " + version);
        System.out.println("Ready to learn.");
        System.out.println("Let's begin.");
    }
}
Exercise

What is the correct signature for the method the JVM calls to start a program?

Exercise

println or print? Read carefully and predict the exact output (two lines).

public class Main {
    public static void main(String[] args) {
        System.out.print("Hello");
        System.out.print(", ");
        System.out.println("world");
        System.out.println("Line two");
    }
}
Exercise

Concatenation check. Predict all three lines. The order of the + operations matters.

public class Main {
    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        System.out.println("Sum: " + a + b);
        System.out.println("Sum: " + (a + b));
        System.out.println(a + b + " is the sum");
    }
}
Exercise

You save this program as Main.java and compile it with javac Main.java. What happens?

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

Recap

  • A Java program is a class containing a method called main; execution starts there and nowhere else.
  • The signature public static void main(String[] args) is exact — public, static, void, the name main, and the String[] parameter are all required, or the program compiles but never starts.
  • System.out.println prints a line and advances; System.out.print prints without advancing.
  • + concatenates left to right, so "Sum: " + 1 + 2 gives Sum: 12; use parentheses to add first.
  • Semicolons end statements, braces define blocks, and capitalisation must be exact.

Next you will turn this skeleton into something reusable by giving it variables and types — the named slots that hold a program's data.

Checkpoint quiz

What does System.out.println do?

Why does every Java statement end with a semicolon?

What does "Score: " + 2 + 3 print?

Go deeper — technical resources