Structure of a Java program (class, main, statements)

public static void main(String[] args) is the most typed line in Java, and the one beginners understand least. In this lesson you'll take a complete program apart piece by piece: package, imports, class, fields, methods, statements, blocks and comments. You'll learn what every word of main means to the JVM, and what System.out.println actually is.

Module 1 · Introduction to Java⏱ 17 minBeginnerNo install needed8 practice problems
1 The story

The canteen token

The college canteen gives every order a token number. Riya wants a program that prints the token and the date. She writes it, it works, and then Arjun Sir points at the first line inside the class and asks: “What does each of those five words do?”

import java.time.LocalDate; public class Main { static String canteen = "Kharghar…"; public static void main(String[] args) { int token = 42; printToken(token); } … import: borrow a ready-made class class: the container for everything field: data the class keeps main: where the JVM starts statements: the actual steps myphatshala.in
Riya

public static void main… honestly, Sir, I just copy it every time. I know it has to be there, but not why.

Arjun Sir

Most students do. But each word is an answer to a question the JVM asks. Can I call it from outside? public. Do I need an object first? static. Will you hand me back a result? void. Which method do I start with? main.

Riya

And String[] args is the words typed after the class name, from the last lesson!

Arjun Sir

Right. Today we'll take your token program apart, piece by piece, and you'll never have to copy it blindly again.

2 Definition

What is the structure of a Java program?

Formal definition (write this in exams)

A Java source file has an optional package declaration, followed by zero or more import statements, followed by one or more type declarations (classes, interfaces, enums or records), of which at most one is public. A class contains members: fields (variables) and methods. Executable code is written as statements inside method bodies, grouped into blocks with curly braces. An application starts from the method public static void main(String[] args).

In simple words

Think of the file as a building. The package is its address. Imports are the things you bring in from outside. The class is the building itself. Fields are what's stored inside, methods are the rooms where work happens, and statements are the individual jobs done in each room. main is the front door, where the JVM always walks in.

Words you'll meet in this lesson

StatementOne complete instruction, usually ending with ;. Example: int token = 42;
BlockStatements grouped by { }. Class bodies, method bodies and loop bodies are blocks.
MethodA named block of code that does one job and can be called again and again.
FieldA variable declared directly inside a class, outside any method.
KeywordA word reserved by Java with a fixed meaning: public, class, static, void, int…
CommentNotes for humans that javac ignores: //, /* */ and /** */.

The order inside a .java file

1. package (optional)package com.myphatshala.canteen; First line if present. Says which folder/group the class belongs to.
2. import (optional)import java.time.LocalDate; Lets you use a class by its short name. java.lang (String, System, Math) is imported automatically.
3. class declarationpublic class Main { … } At most one public class per file.
4. fieldsVariables inside the class: static String canteen = "…";
5. methodsmain plus any helper methods, in any order
6. statementsInside method bodies only, each ending with ;

Exam tip: the order is package → import → class, and it can't change. Inside a class, fields and methods can appear in any order, but statements like System.out.println(…) can't sit directly in a class body: they must be inside a method (or an initialiser block).

3 Types and ways to use it

The building blocks, one by one

Every word of the main method

WordMeaningWhy the JVM needs it
publicAccess modifier: anyone can call this methodThe JVM calls it from outside your class
staticBelongs to the class, not to an objectThe JVM can call it without creating a Main object first
voidReturn type: returns nothingThe JVM doesn't expect a value back (exit codes use System.exit)
mainThe method's nameThe launcher looks for exactly this name
String[] argsParameter: an array of StringsReceives the command-line arguments

Allowed variations: String args[], String... args, any parameter name (String[] input), and the order static public all work. Changing void, removing static or public, or renaming main means classic Java won't find it as the entry point.

Three kinds of comments

Single-line: //

Everything after // to the end of the line is ignored. Used for short notes.

Most common

Multi-line: /* … */

Everything between the markers is ignored, across many lines. Handy for longer explanations.

Blocks of text

Documentation: /** … */

Placed just above a class or method. The javadoc tool turns these into HTML documentation, like the official Java API pages.

For javadoc

Kinds of statements you'll write

KindExampleCovered in
Declarationint token = 42;Module 2
Expression statementtoken = token + 1; · printToken(token);Modules 2 and 5
Control flowif (token > 100) { … } · for (…) { … }Module 3
Returnreturn total;Module 5
Block{ statement1; statement2; }Everywhere
4 Step by step

Build the token program, one layer at a time

Instead of copying the whole program, add one structural piece per step and see why each one is there.

  1. Start with an empty class

    public class Main {
    }
    This compiles, and javac even adds a default constructor. But java Main fails with “Main method not found”: the JVM has a building with no front door.
  2. Add the main method

    public class Main {
        public static void main(String[] args) {
            int token = 42;
            System.out.println("Token #" + token);
        }
    }
    Token #42
    Now the launcher finds main, creates the args array, and runs the two statements in order, top to bottom.
  3. Add a field and a helper method

    The canteen name belongs to the whole program, so it becomes a field. Printing a token is a job we may repeat, so it becomes a method.

    The field is static, so it's stored once with the class, not in main's stack frame. Calling printToken(token) pushes a new stack frame on top of main's.
  4. Import a class from the library

    To print the date we use LocalDate from the java.time package, so we add import java.time.LocalDate; at the top.

    An import doesn't copy any code into your file. It only tells javac that LocalDate means java.time.LocalDate. In the .class file, the full name is stored in the constant pool.
  5. Add comments and check the layout

    Add a short comment above the class and indent each block by four spaces. Your final program is in Part 7.

    javac throws comments and extra spaces away completely: the .class file is identical with or without them. They exist purely for the humans who read the code later, including you.
5 See it happen

public static void main, word by word: both views

Step through the most famous line in Java. Left: the code, with one word highlighted. Right: the question the JVM is asking at that moment.

Decoding the entry point 6 steps
What you see publicstaticvoid main(String[] args) public“Anyone, even code outside this class,may call this method.” static“This method belongs to the class itself.No object has to be created to call it.” void“It gives nothing back when it finishes.” main“The name the launcher searches for.”Main (capital M) or start won't do. String[] args“An array of words typed after the class name.” > java Main Riya 42 System.out.println("Token #42"); class object method And inside main: the most famous statement. myphatshala.in
Behind the screen JVMlauncher code class Main main(…) The JVM's launcher is outside your class. Without public, the door would be locked to it. Class Main(method area, loaded once) static main static canteen Main objects(none exist yet) At start-up there are no objects at all. A static method can be called on the class directly. In bytecode, main's descriptor is: ([Ljava/lang/String;)V [Ljava/lang/String; = String array parameter V = void return type To send an exit code, programs call System.exit(1) instead of returning it. Launcher's search in class Main: printToken(int) ✗ wrong name Main(String[]) ✗ wrong case main(String[]) ✓ public static void If nothing matches, the error is: Main method not found in class Main java Main Riya 42 main's stack frame args→ String[2] [0] "Riya" [1] "42" Even 42 arrives as text: "42", not a number. Converting text to numbers comes in Module 2. Systema class injava.lang (auto-imported) outa static fieldholding aPrintStream object printlna method ofPrintStream PrintStream writes bytes to the console (standard output), then adds a line break. System.err → error output, System.in → keyboard myphatshala.in
6 Real-world use

How real projects are structured

Company projects follow the same rules, just with many more files. Here's how the structure you learned scales up.

Watch it with an example: a three-class fee app

Real programs have many classes. Watch how the JVM starts from the one class that has main and loads the others only when they are needed.

java App → main → other classes 5 steps
Animated example App.classhas main() Student.classname, roll Fee.classamount() JVM memory App loaded main() running Student loaded Fee loaded Riya: fee Rs 45,000 myphatshala.in
src/main/java/com/bank/payments/UpiService.javaaccounts/

1. Packages organise thousands of classes

A banking app might have hundreds of classes. They're grouped into packages such as com.bank.payments and com.bank.accounts, which are also folders on disk. Every file starts with its package line.

package com.bank.payments;→folder com/bank/payments→Easy to find code
main

2. A tiny main in a big application

In a Spring Boot service, main is often just one line: SpringApplication.run(App.class, args);. It starts the framework, which then creates and wires all the other classes.

JVM calls main→main starts Spring→Hundreds of classes ready

3. Javadoc comments become API documentation

Libraries document every public class and method with /** … */ comments. The javadoc tool turns them into web pages, and IDEs show them as pop-up help while you type.

/** Returns the GST amount */→javadoc tool→HTML docs + IDE hints
$ java -jar report.jar --month=10done, exit 0

4. Batch jobs driven by args

Night-time jobs, such as generating monthly statements, are often started by a scheduler with command-line arguments: java -jar report.jar --month=10. The values arrive in args, and the job's exit code tells the scheduler whether it succeeded.

Scheduler→main(String[] args)→Exit code 0 or 1
lint

5. Style checks in code review

Teams agree on layout and naming rules (indentation, braces, one class per file), and tools such as Checkstyle or the IDE's formatter check them automatically before code is merged.

Pull request→Formatter + Checkstyle→Consistent code

Examples are simplified to show the structure. Project layouts vary between companies and frameworks.

7 Run the code

The complete token program

Every structural piece from this lesson in one program. Read the notes, then try the challenges.

import java.time.LocalDate;

/* Prints a canteen token with today's date. */
public class Main {
    static String canteen = "Kharghar Canteen";

    public static void main(String[] args) {
        int token = 42;
        printToken(token);
        System.out.println("Date: " + LocalDate.of(2026, 10, 15));
    }

    // A helper method: prints one token line
    static void printToken(int number) {
        System.out.println(canteen + " - Token #" + number);
    }
}
Kharghar Canteen - Token #42 Date: 2026-10-15
  • import java.time.LocalDate;Lets us write LocalDate instead of java.time.LocalDate. Must come before the class.
  • /* … */ and // …Comments. javac ignores them completely.
  • static String canteen = …;A field: declared in the class, outside every method, so every method can use it.
  • printToken(token);A method call statement. Java jumps into printToken, runs it, and comes back.
  • static void printToken(int number)A helper method with one parameter. It's static so main can call it without an object.
  • { } and indentationBraces mark where each block starts and ends. Indentation is only for humans, but makes the blocks easy to see.
8 Line by line

Follow the program from main into a method and back

Watch the stack: when main calls printToken, a new frame goes on top, and it's removed when the method returns. The static field lives with the class, not in any frame.

Worked examples: real problems, solved and traced in memory

Every Java program has the same skeleton: imports, a class, fields, methods and main. These three programs use each part for a real job. In the trace, watch static fields appear once for the class while each method call gets its own frame.

Example 1Restaurant · tokens

Token slips from a helper method

Problem statement

A restaurant prints a token slip for each order. The restaurant name is the same for every slip, so store it once in a static field. Put the printing in a method and call it for tokens 101 and 102.

Input
tokens 101, 102
Expected output
Udupi Corner | Token #101
Udupi Corner | Token #102
Slips printed: 2

Approach

  1. A static String field holds the name: one copy for the whole class.
  2. printSlip(int token) prints one slip.
  3. main calls it twice.

Solution: run it live

What happens in memory, step by step

Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.

Example 2Library · due dates

Using an import: a library book's due date

Problem statement

A college library lends books for 14 days. Print the issue date and the due date. LocalDate lives in package java.time, so it must be imported at the top of the file.

Input
issued 2026-10-15, 14 days
Expected output
Issued: 2026-10-15
Due:    2026-10-29

Approach

  1. import java.time.LocalDate; before the class.
  2. Create the issue date, then plusDays(14).
  3. Print both.

Solution: run it live

What happens in memory, step by step

Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.

Example 3Shop · pricing

Two methods working together

Problem statement

A shop computes a bill in two steps: apply a 10% discount, then add 5% tax. Write one method for each step and combine them in main.

Input
price 800
Expected output
After discount: Rs 720.0
Final price:    Rs 756.0

Approach

  1. discount(double p) returns 90% of p.
  2. addTax(double p) returns 105% of p.
  3. main passes the result of one method into the other.

Solution: run it live

What happens in memory, step by step

Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.

9 Quiz and revision

Check yourself

Quick revision

Lesson 1.6 in one screen

  • File order: package → imports → class. One public class per file, named like the file.
  • Class members: fields (data) and methods (behaviour). Statements live inside methods.
  • public (JVM can call it) · static (no object needed) · void (returns nothing) · main (fixed name) · String[] args (command-line words).
  • System = class, out = static PrintStream field, println = method.
  • java.lang is auto-imported. Imports don't copy code; they just shorten names.
  • Comments: //, /* */, /** */ (javadoc). javac ignores them.
  • A method call pushes a new stack frame; returning pops it.

Interview and viva questions

Explain public static void main(String[] args).

public so the JVM can call it from outside the class; static so it can be called without creating an object; void because it returns nothing; main is the name the launcher looks for; String[] args receives command-line arguments as an array of strings.

Can we overload the main method?

Yes. You can write other methods named main with different parameters, such as main(int x). But the JVM only uses main(String[] args) as the entry point; the others are normal methods you call yourself.

Can a program run without a main method?

A normal application needs an entry point. Very old Java versions could run code from a static block without main, but that stopped working in Java 7. Frameworks and app servers do have a main; it's just inside the framework rather than your code.

What is the difference between import and #include in C?

#include copies the header file's text into your source before compiling. Java's import copies nothing: it only tells the compiler which full class name a short name refers to. Classes are loaded separately by the JVM at run time.

Why does Java use System.out.println instead of just print?

Because everything in Java belongs to a class. Printing is done by a PrintStream object stored in the static field out of the System class. This design also lets programs redirect System.out to a file or another stream.

Practice problems

Use the parts of a Java program: class, main, static fields, constants, imports and methods. Every output is fixed. The last three are business tasks.

P1Easy

A greeting method

Write static void greet() that prints "Welcome!" and call it from main twice.

Input
(none)
Expected output
Welcome!
Welcome!
Show solution and explanation
public class Main {
    static void greet() {
        System.out.println("Welcome!");
    }

    public static void main(String[] args) {
        greet();
        greet();
    }
}
Welcome! Welcome!

How it works: a method is defined once and can be called many times.

P2Easy

A constant

Declare static final double GST = 0.18; and print the GST on Rs 1,000.

Input
1000
Expected output
GST: Rs 180.0
Show solution and explanation
public class Main {
    static final double GST = 0.18;

    public static void main(String[] args) {
        System.out.println("GST: Rs " + 1000 * GST);
    }
}
GST: Rs 180.0

How it works: final means it can't be changed; constants are written in capitals by convention.

P3Easy

Method with a parameter

Write static int doubleIt(int n) and print doubleIt(21).

Input
21
Expected output
42
Show solution and explanation
public class Main {
    static int doubleIt(int n) {
        return n * 2;
    }

    public static void main(String[] args) {
        System.out.println(doubleIt(21));
    }
}
42

How it works: return sends a value back to the caller.

P4Medium

Import and use

Import java.time.LocalDate and print the weekday of 2026-08-15.

Input
2026-08-15
Expected output
SATURDAY
Show solution and explanation
import java.time.LocalDate;

public class Main {
    public static void main(String[] args) {
        System.out.println(LocalDate.of(2026, 8, 15).getDayOfWeek());
    }
}
SATURDAY

How it works: imports go before the class and let you use the short class name.

P5Medium

Shared counter

A static field visits starts at 0. A method visit() adds 1. Call it three times and print visits.

Input
(none)
Expected output
Visits: 3
Show solution and explanation
public class Main {
    static int visits = 0;

    static void visit() {
        visits = visits + 1;
    }

    public static void main(String[] args) {
        visit();
        visit();
        visit();
        System.out.println("Visits: " + visits);
    }
}
Visits: 3

How it works: a static field lives as long as the class, so every call updates the same value.

P6Business problem

Delivery charge method

Write static int delivery(int km): Rs 20 base + Rs 8 per km. Print charges for 3 km and 7 km.

Input
3, 7
Expected output
3 km: Rs 44
7 km: Rs 76
Show solution and explanation
public class Main {
    static int delivery(int km) {
        return 20 + 8 * km;
    }

    public static void main(String[] args) {
        System.out.println("3 km: Rs " + delivery(3));
        System.out.println("7 km: Rs " + delivery(7));
    }
}
3 km: Rs 44 7 km: Rs 76

How it works: putting the rule in one method means a price change is made in one place. (Illustrative rates.)

P7Business problem

Shop details in constants

Store the shop name and GSTIN as constants and print a receipt header.

Input
(none)
Expected output
Patil Electronics
GSTIN: 27ABCDE1234F1Z5
Show solution and explanation
public class Main {
    static final String SHOP = "Patil Electronics";
    static final String GSTIN = "27ABCDE1234F1Z5";

    public static void main(String[] args) {
        System.out.println(SHOP);
        System.out.println("GSTIN: " + GSTIN);
    }
}
Patil Electronics GSTIN: 27ABCDE1234F1Z5

How it works: constants for fixed business details avoid typos repeated across a program. (Made-up GSTIN.)

P8Business problem

Two-step salary calculation

Write gross(basic) = basic + 40% HRA and net(gross) = gross − 12% PF. Print net for basic Rs 30,000.

Input
30000
Expected output
Net: Rs 36960.0
Show solution and explanation
public class Main {
    static double gross(double basic) {
        return basic * 1.40;
    }

    static double net(double gross) {
        return gross * 0.88;
    }

    public static void main(String[] args) {
        System.out.println("Net: Rs " + net(gross(30000)));
    }
}
Net: Rs 36960.0

How it works: the inner call runs first (42000.0), its result feeds the outer call (36960.0). (Simplified salary rules.)

Real-world scenario questions (asked in company interviews)

Structure questions in companies are about readability, maintainability and how programs talk to the systems around them. Decide your answer first, then open the model answer.

IT services · code reviewFresher

A 400-line main method

You're asked to review a teammate's billing utility. Everything is written inside main: reading the input file, calculating GST, applying discounts, writing the report. It works, but it's 400 lines long. What feedback would you give?

The interviewer is checking: do you understand why code is split into methods, and can you give review feedback politely and concretely?

Show a strong answer

I'd first say what works: the logic is correct and the output is right. Then I'd suggest structure:

  • Split it into methods that each do one job, with clear names: readOrders(), calculateGst(), applyDiscount(), writeReport(). Then main reads like a short summary of the steps.
  • Small methods can be unit-tested one at a time, for example testing GST rules without reading any files.
  • Repeated code becomes one method called many times, so a rule change happens in one place.
  • Later, related methods can move into their own classes (Module 6).

Avoid: “This is bad code, rewrite it.” Review comments should be specific and suggest the next step.

Bank · batch processing1–3 years

The failed job that reported success

A nightly Java job generates account statements. One night the database was down. The job printed an error, but the scheduler marked the run as successful, so nobody was alerted and customers got no statements. The main method catches every exception and prints it. What went wrong?

The interviewer is checking: do you know that main returns void and that the process exit code is how a Java program reports success or failure to the outside world?

Show a strong answer

Schedulers judge a job by its exit code: 0 means success, anything else means failure. Because main caught the exception, printed it and then returned normally, the JVM exited with code 0.

  • After logging the error, call System.exit(1) (or another non-zero code) so the scheduler sees the failure and raises an alert.
  • Alternatively, let the exception escape main: an uncaught exception also makes the JVM exit with a non-zero code.
  • Use a proper logger instead of printing, and add an alert or retry policy in the scheduler.

Avoid: catching every exception in main just to “keep it from crashing”. Hiding failures is worse than crashing.

Product company · production logsFresher

System.out.println in a server

Your first feature works, and you've added System.out.println calls to show what's happening. In review, the senior says: “Please don't use System.out in the service, use the logger.” You know println works. Why does it matter?

The interviewer is checking: do you understand what System.out is, and why real systems need structured logging?

Show a strong answer

System.out is just one PrintStream to standard output. A logging framework (for example SLF4J with Logback) adds what production needs:

  • Levels (DEBUG, INFO, WARN, ERROR) that can be switched on or off without changing code.
  • Automatic timestamps, thread names and class names on every line, which are essential when debugging.
  • Sending logs to files or central systems (like an ELK stack), with rotation so disks don't fill up.
  • Consistent formatting that monitoring tools can search and alert on.

Avoid saying: “println is the same thing.” It works for learning, not for operating a service.

Any company · coding standardsFresher

Naming that fails the style check

Your pull request is blocked by the automated style check. It flags a class named paymentprocess, a method named Calculate_Total, and a file with two public classes. A teammate says, “It compiles, so who cares?”

The interviewer is checking: do you know Java's naming conventions and the structural rules, and why teams enforce them?

Show a strong answer
  • Two public classes in one file won't even compile. One of them must move to its own file named after it.
  • Java conventions: classes in PascalCase (PaymentProcessor), methods and variables in camelCase (calculateTotal), constants in UPPER_SNAKE_CASE (MAX_LIMIT), packages in lowercase (com.shop.payments).
  • Conventions make code instantly readable to every Java developer and keep a large codebase consistent. Automated checks stop small issues taking up reviewers' time.
  • I'd fix the names (the IDE's Rename refactoring updates every usage) and push again.

Avoid saying: “It compiles, so it's fine.” Code is read far more often than it's written.