Lessons
1 · Java Foundations
2 · Object-Oriented Java
3 · Core Java
4 · Collections and Generics
5 · Functional Java
6 · The JVM and Concurrency
7 · Tools and Craft
- 21File I/O and Serialization
- 22Debugging: Errors, Stack Traces, the Debugger and Logging
- 23Maven: What It Does and How to Use It
- 24Git for Java Projects: Commits, Branches, Merging and Pull Requests
- 25Testing with JUnit and Mockito: Unit Tests, Mocks and Their Limits
- 26Project 1: Build an Expense Tracker CLI in Plain Java
8 · Databases and JDBC
9 · Web and Spring
10 · Persistence with JPA
11 · Secure, Tested, Production-Ready
- 36Security Fundamentals and Spring Security: Passwords, JWT, Access Control, CORS and Secrets
- 37Testing Spring Boot Applications: Slice Tests, MockMvc, Real Databases and the Test Pyramid
- 38Production Practices: Configuration, Logging, Docker and Health Checks for Spring Boot
- 39Project 3: The Job Application Tracker API, Assembled and Reviewed
Lesson 1 · Java Foundations
Start Here: What Java Is, How It Runs and Your Roadmap
What Java actually is, how a .java file becomes a running program, what the JDK, JRE and JVM each do, and how to compile and run your first program. Plus the full roadmap of this 41-article course, from zero to a tested Spring Boot API.
For
Complete beginners who want to learn Java properly, from the first program to backend development, and people returning to Java who want a modern baseline.
Level
Before you start
None. You need a computer where you can install software and a text editor. No programming experience is assumed.
On this page
Key takeaways
- Java source code is compiled by javac into bytecode, and the Java Virtual Machine runs that bytecode. That is why the same compiled program runs on different operating systems.
- The JDK contains the tools you develop with, including the compiler. The JVM is the part that runs programs. Install a JDK, not just a runtime.
- The compiler catches some mistakes before the program runs, and the runtime reports others while it runs. Learn to tell them apart by their messages.
- This course uses Java 21 or newer, runs every example on both 21 and 25, and labels older style code so you can recognise it in interviews and existing projects.
- Learn in order: foundations, object-oriented Java, core APIs, collections, functional Java, the JVM and concurrency, tools, then databases and Spring. Each project applies what came before.
You have almost certainly used software written in Java without knowing it. Android apps, many banking and payment systems, large online shops and a great deal of company back-office software run on it. Whether you want to build backend services, prepare for a Java interview or simply learn how serious software is built, Java is a reasonable place to start. It is not the only place, and it is not "the best language". It is a mature, widely used one, and learning it well teaches ideas that carry over to other languages.
This course takes you from "what is Java?" to building and testing a Spring Boot REST API backed by a database, and then to explaining what you built in an interview. This first article answers the foundational question: what happens between the moment you type Java code and the moment something appears on screen?
What you will learn
#- What Java is, and what "write once, run anywhere" really means.
- The journey from source code to a running program.
- The difference between the JDK, the JRE and the JVM.
- How to compile and run a program, and the shortcut for single files.
- Compile-time errors versus runtime errors.
- How this course is organised, and how it treats modern and older Java.
What problem does Java solve?
#A computer's processor understands only its own machine instructions, and those differ between processor families and operating systems. A program compiled for Windows on one kind of processor will not run on Linux on another. Before Java, shipping software to many platforms usually meant compiling it separately for each one, and fixing platform differences by hand.
Java took a different route. Instead of compiling to machine code for one specific computer, the Java compiler produces bytecode, a compact instruction set for an imaginary computer called the Java Virtual Machine (JVM). On every platform you install a real program that implements that imaginary computer and runs the bytecode. The Java Virtual Machine Specification describes this: the JVM knows nothing of the Java language itself, only of a binary format called the class file format, which contains bytecode instructions plus a symbol table and other supporting information. Because the bytecode is the same everywhere, the same compiled program can run on any system that has a JVM.
That is the idea behind "write once, run anywhere". It is worth stating carefully: you do not get platform independence for free. Your code still has to avoid assumptions about file paths, line endings and so on. What you get is that you do not need to recompile for each operating system.
A useful side effect is that the JVM is not tied to the Java language. Other languages, such as Kotlin and Scala, compile to the same bytecode. You will meet this again when we look at the JVM in How the JVM Runs Your Code.
The mental model: from source to screen
#Here is the whole journey in one picture.
Main.java Main.class running program(source code) ---> (bytecode) ---> JVM ---> (machine code on your CPU) you write javac compiles java launches and runs itStage | What exists | Who produces it | Where you see it |
|---|---|---|---|
Source | A text file ending in | You | Your editor |
Compile |
| The compiler, | A file next to your source, or an output folder |
Load and run | A running process | The JVM, started by the | Your terminal or application |
The javac tool, as Oracle's documentation describes it, reads source files containing module, package and type declarations written in Java and compiles them into class files that run on the JVM. When you run the java command, the JVM loads those class files, verifies them, and executes them, translating hot spots to optimised machine code as the program runs. You do not need the details of that last part yet. Article 18 covers it.
JDK, JRE and JVM: three terms, one relationship
#These three abbreviations are mixed up constantly, and interviewers ask about them.
Term | Stands for | What it is |
|---|---|---|
JVM | Java Virtual Machine | The program that loads and runs bytecode. Different vendors make compatible ones |
JRE | Java Runtime Environment | The JVM plus the standard libraries needed to run Java programs |
JDK | Java Development Kit | Everything in the JRE, plus the tools for developing: the compiler |
The relationship is nesting: the JDK contains the JRE, and the JRE contains the JVM.
Today you will almost always install a JDK. Many vendors have stopped publishing separate runtime-only downloads, and for development you need the compiler anyway. The term JRE still appears in documentation, interviews and older tutorials, so you should know what it means. If an exercise says "install Java", it means "install a JDK".
Versions: what to install
#Java has a predictable release schedule: a new feature release arrives every six months, and some releases are designated long-term support (LTS) releases, which vendors support for longer. As of October 2026, the OpenJDK project lists JDK 27 as the most recent release (generally available on 15 September 2026), and JDK 25 (September 2025) is the most recent LTS release. JDK 21 is the previous LTS release.
This course uses a deliberate baseline:
- Java 21 or newer. Every complete program in the course was compiled and run on both JDK 21 and JDK 25, and the printed output is the real output.
- Why 21 as the floor? It is the oldest release that includes everything the course teaches as standard modern Java: records, sealed classes, pattern matching for
switch, virtual threads and sequenced collections. If you install JDK 25, everything still works. If you are stuck on an older version such as 17 or 11, most of the first half of the course still applies, but later articles will tell you when a feature needs a newer release. - Which vendor? Several organisations build and distribute JDKs from the OpenJDK source, and Oracle publishes its own builds. They are compatible for learning purposes. Pick one that your employer or a trusted source recommends, and keep it up to date.
Java 8, released in 2014, is still found in many existing systems and interviews. The course teaches the parts of Java 8 that remain important (for example lambdas and streams, which arrived in 8) and labels older style code as Older style next to the Modern Java alternative, so that you can read both.
Set up your tools
#- Install a JDK (version 21 or newer) and make sure it is on your path.
- Check it by opening a terminal and running these two commands. Both should print a version number.
java -versionjavac -versionIf java works but javac is "not found", you have a runtime without the compiler, or your path points at an older installation. Fix that before continuing.
- Choose an editor. A plain text editor is enough for the first articles, and learning to compile on the command line once is valuable. After that, an IDE such as IntelliJ IDEA (the free Community edition) or a code editor with Java extensions will save time. Article 22 uses an IDE's debugger.
Your first program, line by line
#Create a file named Main.java containing the program below. File names matter in Java, as you will see.
// File: Main.javapublic class Main { public static void main(String[] args) { System.out.println("Hello, Java!"); int items = 3; double price = 49.5; System.out.println("Total: " + items * price); }}Hello, Java!Total: 148.5Every part has a job:
public class Main { ... }declares a class namedMain. In Java, all code lives inside classes. Because the class ispublic, the file must be namedMain.java.public static void main(String[] args)is the entry point. When you run the program, the JVM looks for exactly this method and starts there.publicmeans anyone can call it,staticmeans it belongs to the class rather than to an object (you will understand why in article 4),voidmeans it returns nothing, andString[] argsholds any command-line arguments.System.out.println(...)prints a line of text.System.outis a stream connected to your terminal, andprintlnwrites text followed by a line break.int items = 3;anddouble price = 49.5;declare variables: named storage with a type. Article 2 explains types properly."Total: " + items * pricemultiplies first (3 times 49.5), then joins the number to the text. You can see that the result is printed as148.5.
Compile it, then run it
#In the folder that contains Main.java, run:
javac Main.javajava MainThe first command invokes the compiler. If there are no errors it prints nothing, and creates Main.class next to your source file: that is the bytecode. The second command starts a JVM and tells it to run the class Main. Note that you write java Main, not java Main.class: you give the JVM a class name, and it finds the file.
The shortcut for a single file
#Since Java 11, the java launcher can compile and run a single source file in one step:
java Main.javaJEP 330, which introduced this, describes it as compiling the source into memory and running the first class found in the file, informally equivalent to compiling with javac into memory and then running. It leaves no .class file behind, and it only sees one source file. It is excellent for experiments. For real projects, you will use a build tool (article 23).
What the bytecode looks like
#You can look inside a class file with the javap tool from the JDK. Here is a tiny method:
static int add(int a, int b) { return a + b;}Compiling it and running javap -c -p Main shows the bytecode for add (output from JDK 21, with indentation that varies slightly between versions):
static int add(int, int); Code: 0: iload_0 1: iload_1 2: iadd 3: ireturnRead it as instructions for a simple stack-based machine: push the first argument, push the second, add the two values on top of the stack, return the result. You will never write this by hand. The point is that bytecode is a small, platform-neutral instruction set, and that "compiling Java" means translating your readable code into this form.
Two kinds of errors
#Beginners meet errors constantly, so it helps to learn the two families early.
Compile-time errors are found by javac before anything runs. The code violates the language rules, for example by putting text in a number variable:
// File: Main.javapublic class Main { public static void main(String[] args) { int count = "three"; System.out.println(count); }}Main.java:4: error: incompatible types: String cannot be converted to int int count = "three"; ^1 errorThe message names the file, the line, and the problem: a String cannot be converted to int. The compiler marks the position with a caret. No .class file is produced, so there is nothing to run.
Runtime errors (exceptions) happen while the program runs, because something was valid code but impossible to do:
// File: Main.javapublic class Main { public static void main(String[] args) { int[] scores = {80, 90, 70}; System.out.println(scores[5]); }}Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3 at Main.main(Main.java:5)The compiler accepted this, since an array index is just an int. The JVM discovered while running that index 5 does not exist in an array of length 3, and reported it as an ArrayIndexOutOfBoundsException with the line where it happened (the second line, starting with at, is part of the stack trace, which article 22 teaches you to read in detail). The first output line is the one to read first: the exception type and its message.
A good habit starts here: read the first line of every error message carefully before changing anything. Most Java errors tell you exactly what is wrong and where.
The file name rule
#A public class must live in a file of the same name. The compiler enforces it:
// File: Greeter.javapublic class Welcome { public static void main(String[] args) { System.out.println("Hello"); }}Greeter.java:2: error: class Welcome is public, should be declared in a file named Welcome.javapublic class Welcome { ^1 errorThis is one of the most common first-day errors, and it shows that the file name is part of Java's rules, not just a convention.
How the program is structured
#Even in this tiny example you can see the general structure that every Java program shares:
Piece | Purpose | Example |
|---|---|---|
| Groups related classes, like folders |
|
| Lets you use a class by its short name |
|
Class declaration | The unit that holds code and data |
|
Methods | Named blocks of code |
|
Statements | Individual instructions, each ending in |
|
Java is case sensitive (Main and main are different names). The conventions are UpperCamelCase for class names and lowerCamelCase for methods and variables. Following them makes your code readable to other Java developers.
The roadmap
#This course is 41 articles in 12 modules. The order is deliberate: each module prepares you for the next.
Module | Articles | What you will be able to do afterwards |
|---|---|---|
1. Java Foundations | 1 to 3 | Write small programs with data, decisions, loops and methods |
2. Object-Oriented Java | 4 to 6 | Model problems with classes, inheritance, interfaces and composition |
3. Core Java | 7 to 10 | Use |
4. Collections and Generics | 11 to 14 | Choose and use |
5. Functional Java | 15 to 17 | Use lambdas, streams and |
6. JVM and Concurrency | 18 to 20 | Explain memory and garbage collection, and write correct concurrent code |
7. Tools and Craft | 21 to 26 | Use files, a debugger, Maven, Git and JUnit, and build Project 1 |
8. Databases and JDBC | 27 to 29 | Use SQL and JDBC, and build Project 2 |
9. Web and Spring | 30 to 33 | Explain HTTP and REST, and build a Spring Boot API |
10. Persistence with JPA | 34 to 35 | Use JPA and Hibernate without falling into their traps |
11. Secure, Tested, Production-Ready | 36 to 39 | Secure, test and containerise the API, and build Project 3 |
12. Interviews and Readiness | 40 to 41 | Explain what you know, and check that you are ready |
Three projects tie it together: an Expense Tracker CLI, the same tracker backed by PostgreSQL, and a Job Application Tracker API built with Spring Boot.
How to study
#- Type the code yourself. Copying and pasting skips the part that teaches you.
- Predict before you run. Before running an example, write down what you think it will print. When you are wrong, you have found something to learn.
- Break things on purpose. Remove a semicolon, change a type, and read the error.
- Do the exercises before opening the solutions.
- Build the projects. Reading about Java and writing Java are very different skills.
Every article follows a similar shape: a problem, an intuition, an example, the formal idea, code, trade-offs, mistakes, exercises and links. When a feature is specific to a newer version, the article says which. When facts about tools or releases could change, they are tied to a source in the article's list, and stated "as of October 2026".
Common mistakes
#- Installing only a runtime. If
javacis missing, you cannot compile. - A class name that does not match the file name for a public class.
- Running
java Main.class. Usejava Main, orjava Main.javafor single-file source. - Forgetting to recompile after editing, then wondering why nothing changed.
- Ignoring the first line of an error message.
- Believing that platform independence is automatic. The JVM hides the operating system, not every assumption your code makes.
- Treating Java as old and finished. The language has changed substantially since Java 8, and this course teaches the modern forms.
Exercises
#Exercise 1
Trace the journey
#For the command sequence javac Main.java followed by java Main, say what file is created, which tool creates it, and which tool reads it.
Exercise 2: Predict the error
#A learner saves the following as Main.java. Is the problem a compile-time error or a runtime error, and why? public class Main { public static void main(String[] args) { String name = "Asha"; int length = name; } }
Exercise 3: Fix the setup
#You type javac Main.java and see 'javac' is not recognized as an internal or external command (or command not found), but java -version works. What is the most likely cause, and what do you do?
Exercise 4: Explain it to a friend
#In three or four sentences, explain how the same compiled Java program can run on both Windows and Linux. Use the words bytecode and JVM.
Show solutionHide solution
javac Main.java creates Main.class (bytecode). The compiler, javac, creates it. The java command starts a JVM, which loads and reads Main.class.
If your source file declares other classes, one class file is created for each of them. The key idea is the division of work: javac translates source to bytecode once, and the JVM executes bytecode every time you run.
Exercise 2
Show solutionHide solution
It is a compile-time error. int length = name; tries to store a String in an int variable, and the compiler can see that the types are incompatible without running anything. javac would report that a String cannot be converted to int and produce no .class file.
A runtime error needs the program to start. A typical runtime example is reading an array element that does not exist, or dividing an integer by zero.
Exercise 3
Show solutionHide solution
The most likely cause is that you have a Java runtime but not a JDK on your path, or that the JDK's bin folder is not on the path while a runtime's folder is. java is part of both, but javac is only part of the JDK.
Fix: install a JDK (version 21 or newer), make sure its bin directory is on your path (or that your installer did that), open a new terminal window so the path is refreshed, and check javac -version again. If both commands report different versions, you have two installations, and the path order decides which one runs.
Exercise 4
Show solutionHide solution
An example: "When I compile my Java code, the compiler does not produce instructions for Windows or Linux. It produces bytecode, which is a standard set of instructions for an imaginary machine called the Java Virtual Machine. Each operating system has its own JVM that knows how to run that bytecode on its hardware. So the same bytecode file works on both, as long as both have a JVM. The JVM is what changes from system to system, not my compiled program."
Where to go next
#- Next: Variables, Types, Operators and Arrays teaches how Java stores and combines data.
- When you reach the JVM module, How the JVM Runs Your Code returns to class loading, memory and the JIT compiler.
- For a first look at Java in the context of algorithms, the site's DSA From Zero to Job-Ready: A Practical Guide with Java uses a small subset of Java for problem solving.
Sources & further reading
- Technology
- Software Engineering
- #beginners
- #Java
- #Java backend
- #Java basics
- #Java interview
- #JPA
- #JVM
- #learn Java
- #Spring Boot
- #SQL
Connected lessons
Linked from 2 guides
Other pages in the library that point here.
Keep reading
More in Technology →Guide · Technology
Java Essentials for DSA
Guide · Technology
SQL for Beginners: Learn to Query a Database With Real Examples
Course · Technology
DSA From Zero to Job-Ready: A Practical Guide with Java

