Java Learning Notes — Telusko Core Java | Video 04
In the previous lesson, I finally wrote my first Java program and learned the basic:
Write → Compile → Run
workflow.
But after writing a simple Java program, I realized that there was much more happening behind the scenes.
I kept seeing terms like:
- Bytecode
.class- JVM
- JRE
- JDK
main()javac- WORA
And I had questions like:
What exactly is bytecode?
Why doesn't Java run the
.javafile directly?What is the difference between JDK, JRE and JVM?
If Java is platform independent, why is the JVM platform dependent?
And why does Java need
public static void main(String[] args)?
This lesson helped me connect these pieces.
As I worked through it, I realized that the easiest way to understand Java's execution model is to follow the journey of a Java program from the moment I write it until I see the output.
This article explains what I learned from the lesson, along with additional research I used to make these concepts easier to understand.
What This Article Covers
In this article, I will answer these eight questions:
- What is bytecode?
- What does
javacdo? - Why is Java considered platform independent?
- Why is the JVM platform dependent?
- What is the purpose of
main()? - What is the difference between
java Helloandjavac Hello.java? - What do JDK, JRE and JVM stand for?
- What does WORA mean?
I will also connect all of these concepts into one simple execution flow.
1. What is bytecode?
What I understood first
Before this lesson, I knew that Java code gets compiled.
But I didn't really understand:
Compiled into what?
The answer is:
Bytecode.
When I write Java source code in a file such as:
Hello.java
the Java compiler does not normally convert it directly into machine code specific to Windows, Linux, or macOS.
Instead, it converts the Java source code into bytecode.
The simplified process is:
Java Source Code
↓
javac
↓
Bytecode
↓
JVM
↓
Execution
The bytecode is usually stored inside a .class file.
For example:
Hello.java
↓
Hello.class
So I can think of:
.java
↓
Source code
.class
↓
Bytecode
Why doesn't Java directly create Windows or Linux machine code?
This is where Java's portability becomes important.
If the compiler generated machine code specifically for Windows, that output would not necessarily work directly on Linux or macOS.
Instead, Java uses an intermediate representation:
Bytecode
The JVM on each supported platform understands and executes that bytecode.
So:
Same Bytecode
│
┌──────────┼──────────┐
↓ ↓ ↓
Windows Linux macOS
JVM JVM JVM
This design is one of the major reasons Java became known for portability.
Is bytecode the same as machine code?
No.
This distinction is important.
Machine code is instructions designed for a specific processor architecture.
Java bytecode is an intermediate instruction format designed for the JVM.
So I remember:
Java Source Code
↓
Bytecode
↓
JVM
↓
Platform-specific execution
🧠 Easy to Remember
Bytecode = compiled Java instructions stored in
.classfiles and executed by the JVM.
🎯 Short Interview Answer
Bytecode is the intermediate instruction format produced by the Java compiler from Java source code. It is stored in
.classfiles and executed by the JVM.
2. What does javac do?
What I understood first
I already learned about javac in Video 03, but this lesson helped me understand its role in the complete Java execution model.
javac is the:
Java compiler
Its job is to compile Java source code into bytecode.
For example:
javac Hello.java
If the source code is valid, the compiler can produce:
Hello.class
So:
Hello.java
↓
javac
↓
Hello.class
The .class file contains the bytecode.
What does the compiler actually check?
The compiler doesn't simply convert text into another file.
It also checks whether the Java source code follows the language's rules.
For example, if I write invalid Java syntax, the compiler can report an error.
Suppose I forget a semicolon:
System.out.println("Hello World")
Running:
javac Hello.java
can produce a compilation error.
So I can think of javac as the stage that takes my Java source code and prepares it for execution by the JVM.
javac vs java
This distinction is extremely important:
javac
↓
Compile
java
↓
Run
For example:
javac Hello.java
compiles the source file.
Then:
java Hello
runs the compiled class.
🧠 Easy to Remember
javac→ compile
java→ run
🎯 Short Interview Answer
javacis the Java compiler. It compiles Java source code into bytecode, which is stored in.classfiles and later executed by the JVM.
3. Why is Java considered platform independent?
What I understood first
This was one of the most important concepts for me.
We often hear:
Java is platform independent.
But what exactly does that mean?
It does not mean that Java magically ignores the operating system.
It means that Java's execution model allows the same compiled bytecode to be used across different supported platforms through their appropriate JVM implementations.
The complete picture
Suppose I write:
Hello.java
I compile it:
javac Hello.java
and get:
Hello.class
That .class file contains bytecode.
Now imagine I move that compiled application to another supported operating system.
The JVM available on that platform can execute the bytecode.
So:
Java Source
↓
javac
↓
Bytecode
↓
┌──────────┼──────────┐
↓ ↓ ↓
Windows JVM Linux JVM macOS JVM
↓ ↓ ↓
Run Run Run
This is the basic idea behind Java's platform independence.
What is actually platform independent?
The important distinction is:
Java bytecode is designed to be portable.
The JVM itself is not identical across operating systems.
There can be different JVM implementations for different platforms.
That brings us to the next question.
🧠 Easy to Remember
Same bytecode + different platform JVMs = Java portability
🎯 Short Interview Answer
Java is considered platform independent because Java source code is compiled into platform-independent bytecode that can be executed on different supported operating systems through compatible JVM implementations.
4. Why is the JVM platform dependent?
What I understood first
At first, I found this confusing:
Java is platform independent, but the JVM is platform dependent. How can both be true?
The answer becomes simple when I separate the two.
Java bytecode is portable
The bytecode generated from Java source code is designed to be portable across supported platforms.
For example:
Hello.class
can be transferred to another compatible platform.
The JVM interacts with the operating system
The JVM, however, needs to work with the underlying operating system and hardware.
For example, a JVM running on Windows needs to interact with Windows.
A JVM running on Linux needs to interact with Linux.
A JVM running on macOS needs to interact with macOS.
So we can think of:
Same Java Bytecode
│
┌─────────────┼─────────────┐
↓ ↓ ↓
Windows JVM Linux JVM macOS JVM
↓ ↓ ↓
Windows Linux macOS
The bytecode remains portable, but the JVM implementation is adapted to the platform.
This is the important distinction
Java/bytecode → platform independent
JVM → platform dependent
This distinction cleared up the apparent contradiction for me.
🧠 Easy to Remember
Java bytecode travels.
The JVM adapts to the platform.
🎯 Short Interview Answer
The JVM is platform dependent because each operating system and hardware environment requires a JVM implementation capable of interacting with that specific platform. Java bytecode remains portable because compatible JVMs execute it on different platforms.
5. What is the purpose of main()?
What I understood first
In the previous lesson, I saw code like:
```java id="r8w3tz"
System.out.println("Hello World");
But that statement alone wasn't enough to create a normal Java application.
I needed something like:
```java
public class Hello {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
The important new part was:
public static void main(String[] args)
At this stage, I don't need to memorize the meaning of every keyword yet.
The most important thing is to understand:
main()provides the standard entry point for a Java application.
What does "entry point" mean?
Think about a program as a journey.
The JVM needs to know:
"Where should I start executing this application?"
For a standard Java application launched with the Java launcher, the main() method provides that starting point.
So conceptually:
Start Java Application
↓
Find main()
↓
Begin execution
↓
Run statements
↓
Output
The standard main method
The traditional form introduced here is:
public static void main(String[] args)
For now, I remember the complete signature.
Later, I can learn what:
publicstaticvoidString[]args
actually mean.
Trying to understand every keyword immediately can make the first Java lesson unnecessarily overwhelming.
Example
public class Hello {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
Here:
class Hello
↓
contains main()
↓
JVM starts application execution there
Is main() the only possible entry point in Java?
For the traditional standalone Java application model being taught here, the main method is the standard entry point.
Different Java technologies can have different application startup mechanisms, but for learning Core Java fundamentals, the important rule is:
The JVM looks for the recognized
mainmethod when launching a standard Java application.
🧠 Easy to Remember
main()= starting point of a standard Java application
🎯 Short Interview Answer
The
main()method serves as the standard entry point for a standalone Java application. The Java launcher invokes this method to begin application execution.
6. What is the difference between java Hello and javac Hello.java?
What I understood first
These two commands look very similar, so it is easy to mix them up:
javac Hello.java
and:
java Hello
But they perform completely different jobs.
javac Hello.java
This means:
Compile the Java source file.
The process is:
Hello.java
↓
javac
↓
Hello.class
The .java file is the source code.
The .class file contains bytecode.
java Hello
This means:
Launch the compiled
Helloclass.
The Java launcher starts the JVM and loads the class so that the standard application entry point can be invoked.
The command normally uses the class name, not the .java or .class filename extension:
java Hello
not:
java Hello.java
for the traditional compile-then-run workflow being introduced here.
And not:
java Hello.class
The complete sequence
Write:
Hello.java
↓
Compile:
javac Hello.java
↓
Creates:
Hello.class
↓
Run:
java Hello
↓
JVM
↓
Output
🧠 Easy to Remember
javac Hello.java→ Create bytecode
java Hello→ Run the compiled class
🎯 Short Interview Answer
javac Hello.javacompiles the Java source file into bytecode, whilejava Hellolaunches the compiled class and starts the application through the JVM.
7. What do JDK, JRE and JVM stand for?
What I understood first
This was probably the most confusing group of terms for me.
I kept seeing:
JDK
JRE
JVM
They all sounded like different versions of the same thing.
The easiest way I found to understand them is to think about their roles.
JDK
└── JRE
└── JVM
This is the conceptual hierarchy used in the lesson.
JVM — Java Virtual Machine
The JVM is responsible for:
Executing Java bytecode.
Think:
.class
↓
Bytecode
↓
JVM
↓
Execution
JRE — Java Runtime Environment
The JRE represents the environment required to run Java applications.
The lesson's conceptual model includes:
- JVM
- Runtime libraries/components
So:
JRE
├── JVM
└── Runtime libraries/components
The key idea is:
JRE → runtime
JDK — Java Development Kit
The JDK is for development.
It includes development tools such as the Java compiler.
So:
JDK
├── Development tools
└── Runtime components
↓
JRE
↓
JVM
This is a conceptual model that is useful for learning.
A practical modern note
One thing I discovered while researching this topic is that modern Java distributions don't always package a separate downloadable product called a "JRE" in the same way older Java distributions did.
For learning the architecture, the:
JDK → JRE → JVM
model is still useful.
But when installing modern Java, I generally install a JDK for development rather than looking for a separate JRE download.
The simplest distinction
If I forget everything else, I want to remember:
JDK
↓
Develop Java
JRE
↓
Run Java
JVM
↓
Execute bytecode
🧠 Easy to Remember
JDK → Development
JRE → Runtime
JVM → Executes bytecode
Or:
JDK contains the tools I need to build; the runtime environment lets Java applications run; the JVM executes the bytecode.
🎯 Short Interview Answer
JDK stands for Java Development Kit and provides development tools. JRE stands for Java Runtime Environment and provides the environment required to run Java applications. JVM stands for Java Virtual Machine and executes Java bytecode.
8. What does WORA mean?
What I understood first
I first encountered WORA in the introduction lesson:
Write Once, Run Anywhere
But this lesson made the idea much clearer because now I understood bytecode and the JVM.
How WORA works
Suppose I write:
```text id="o4y7q1"
Hello.java
I compile it:
```bash id="n3k5r8"
javac Hello.java
and get:
Hello.class
The .class file contains bytecode.
Now I can think of that bytecode as being portable across supported platforms because each platform can have a compatible JVM.
Hello.class
Bytecode
│
┌──────────┼──────────┐
↓ ↓ ↓
Windows Linux macOS
JVM JVM JVM
↓ ↓ ↓
Run Run Run
That's the basic idea behind:
Write Once, Run Anywhere
Why isn't the JVM itself portable in the same way?
Because the JVM has to interact with the underlying operating system and hardware.
So:
Bytecode
↓
Portable
JVM
↓
Platform-specific implementation
This distinction is the key to understanding Java's platform independence.
Is WORA an absolute guarantee?
Not literally.
A Java application can still depend on things such as:
- Native libraries
- Operating-system-specific features
- External services
- Environment configuration
- File-system assumptions
So I understand WORA as a description of Java's portable bytecode + JVM execution model, not as a promise that every application will work everywhere without any configuration.
🧠 Easy to Remember
WORA = Write Once, Run Anywhere
And the mechanism is:
Source → Bytecode → Platform-specific JVM → Execution
🎯 Short Interview Answer
WORA stands for Write Once, Run Anywhere. Java achieves this portability by compiling source code into bytecode that can be executed on different supported platforms through compatible JVM implementations.
🔄 The Complete Java Execution Model
After learning all these concepts, I found it much easier to understand Java as a complete process instead of memorizing separate definitions.
Step 1 — Write source code
I create:
Hello.java
and write:
public class Hello {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
Step 2 — Compile
I run:
javac Hello.java
The compiler converts the source code into bytecode.
Hello.java
↓
javac
↓
Hello.class
Step 3 — Launch
I run:
java Hello
The Java launcher starts the runtime and loads the class.
Step 4 — JVM executes bytecode
The JVM loads and executes the bytecode.
Step 5 — main() provides the starting point
The standard main() method provides the entry point from which the application begins execution.
Step 6 — Output appears
Finally:
Hello World
So the complete picture becomes:
Hello.java
│
↓
javac
│
↓
Hello.class
Bytecode
│
↓
java Hello
│
↓
JVM
│
↓
main()
│
↓
Output
This is the mental model I want to carry forward.
🧩 JDK vs JRE vs JVM — Simple Comparison
| Component | Main Purpose | Think |
|---|---|---|
| JDK | Java development | Build |
| JRE | Java runtime environment | Run |
| JVM | Executes bytecode | Execute |
The conceptual relationship from the lesson is:
JDK
↓
JRE
↓
JVM
And the execution flow is:
.java
↓
javac
↓
.class
↓
JVM
↓
Output
⚠️ Common Beginner Mistakes
Confusing java and javac
Remember:
javac → compile
java → run
Running the source filename with java
Traditional compile-then-run workflow:
javac Hello.java
java Hello
not:
java Hello.java
Running .class with the Java launcher
Use:
java Hello
not:
java Hello.class
Thinking the JVM is platform independent
The bytecode is designed to be portable.
The JVM implementation is platform-specific.
Thinking JDK and JVM are the same thing
They are not.
JDK → Development tools
JRE → Runtime environment
JVM → Executes bytecode
Forgetting the main() method
A standard standalone Java application needs an appropriate entry point for the Java launcher to start execution.
For the traditional form:
public static void main(String[] args)
Assuming WORA means zero configuration
Java provides strong portability, but applications can still have platform-specific dependencies.
🧠 One-Minute Revision Sheet
If I have only one minute to revise this lesson, I want to remember:
.java
↓
Java source code
javac
↓
Java compiler
.class
↓
Bytecode
JVM
↓
Executes bytecode
main()
↓
Standard application entry point
JDK
↓
Development
JRE
↓
Runtime
JVM
↓
Execution
WORA
↓
Write Once, Run Anywhere
And the complete workflow:
Write
↓
Compile
↓
Bytecode
↓
JVM
↓
main()
↓
Execute
↓
Output
🎯 8 Interview Questions — Super Short Answers
What is bytecode?
Bytecode is the intermediate code produced by the Java compiler and stored in
.classfiles. The JVM executes it.
What does javac do?
javaccompiles Java source code into bytecode.
Why is Java platform independent?
Java source code is compiled into portable bytecode that can run on different platforms through compatible JVM implementations.
Why is the JVM platform dependent?
The JVM must interact with the specific operating system and hardware platform, so JVM implementations are platform-specific.
What is the purpose of main()?
main()is the standard entry point used to start a standalone Java application.
What is the difference between java Hello and javac Hello.java?
javac Hello.javacompiles the source code, whilejava Hellolaunches the compiled class.
What are JDK, JRE and JVM?
JDK provides development tools, JRE provides the runtime environment, and JVM executes Java bytecode.
What does WORA mean?
WORA means Write Once, Run Anywhere and refers to Java's portable bytecode execution model across supported platforms.
What I Learned From This Lesson
This lesson connected almost everything I had learned in the previous three lessons.
At first, I was looking at these as separate terms:
Java
javac
.class
JVM
JRE
JDK
main()
WORA
Now I can connect them.
Java Source Code
↓
.java
↓
javac
↓
Bytecode
↓
.class
↓
JVM
↓
main()
↓
Execution
↓
Output
And around that execution process:
JDK
↓
Development tools
JRE
↓
Runtime environment
JVM
↓
Executes bytecode
The biggest thing I understood is that Java's platform independence doesn't mean the JVM is the same everywhere.
Instead:
The bytecode is portable, while each platform provides an appropriate JVM implementation to execute it.
That one idea made WORA much easier for me to understand.
A Note for Other Beginners
If you are confused by JVM, JRE, JDK and bytecode, don't try to memorize four definitions separately.
Start with one simple journey:
Write Java
↓
.java
↓
javac
↓
.class
↓
Bytecode
↓
JVM
↓
main()
↓
Output
Then remember the roles:
JDK → develop
JRE → runtime
JVM → execute
Once this mental model becomes clear, many later Java concepts become much easier to understand.
📚 Related Java Learning Resources
This article is part of my Java Learning Notes — Telusko Core Java series.
If you are following the series from the beginning:
👉 Video 01 — Java Introduction: 8 Questions I Had as a Beginner and Their Easy Answers
👉 Video 02 — Setting Up Java: 6 Questions I Had About JDK, VS Code, LTS and PATH
👉 Video 03 — Writing Your First Java Code: 5 Questions I Had as a Beginner
I also wrote a separate article while researching the history behind Java:
👉 Java Introduction: What Is Java, Who Created It, and How Sun Microsystems Became Oracle?
🔗 My Java Learning Notes
I am maintaining the complete structured notes and resources in my GitHub repository.
👉 Java Learning Notes — Telusko Core Java
The GitHub repository contains my concise learning notes and resources, while these DEV.to articles go deeper into the questions and concepts that I found confusing during my learning.
Final Takeaway
For me, Video 04 was the lesson where the Java execution model finally started making sense.
I can now look at:
Hello.java
and understand what happens next:
Hello.java
↓
javac
↓
Hello.class
↓
Bytecode
↓
JVM
↓
main()
↓
Output
And I can remember the three terms that initially confused me:
JDK → Development
JRE → Runtime
JVM → Execution
The next step is to stop just understanding how Java runs and start understanding the actual Java language itself — variables, data types, and how we store information in a program.
This is part of my ongoing Java learning journey. I'm documenting what I learn, the questions I get stuck on, and the explanations that finally make the concepts click for me — hopefully they can help another beginner too.
Top comments (0)