Unit 01 · lesson
Source Code Is Not the Program the JVM Executes
When you write Java, you create source code. The Java Virtual Machine does not directly execute that source text.
A useful first model is:
Java source crosses two execution boundaries
Compilation and runtime are different stages, and each produces different evidence.
- SOURCEJava source expresses programmer intentcompile
- COMPILERchecks syntax and type rulesemit
- BYTECODE.class representation for the JVMexecute
- JVMruns accepted bytecodeobserve
- BEHAVIORoutput, state changes, exceptions, or wrong results
That model is simple, but it explains a surprising amount of Java.
What the compiler does
A compiler checks whether your source follows the rules of the language and translates accepted code into another representation. In normal Java project work, javac produces .class files containing JVM bytecode.
The compiler is not asking, "Did the programmer mean something reasonable?" It is asking whether the program is structurally valid Java and whether required type relationships make sense.
Consider:
void main() {
int students = 24;
IO.println(students);
}
students is declared as an int. The value 24 fits that type. IO.println can print it. The program can move past compilation.
Now change one line:
int students = "twenty-four";
A human understands the idea. Java does not silently convert the text into an integer. The source violates the declared type relationship, so compilation stops.
That is a compile-time failure. The JVM never gets a runnable version of this program.
What the JVM does
The Java Virtual Machine executes Java bytecode and provides the runtime environment used by the program.
This separation is part of Java's portability model. Your source is not rewritten separately for every application you create. Java compilers produce bytecode defined for the JVM, and JVM implementations provide the platform-specific runtime work.
Do not turn "write once, run anywhere" into a magical claim that all systems behave identically. Programs still interact with operating systems, files, networks, fonts, time zones, native libraries, memory limits, and other environment-specific details. The JVM creates an important portability layer; it does not erase the environment.
Three different places a program can fail
Start separating failures now.
1. Before execution
void main() {
int count = "5";
}
The compiler rejects the type mismatch.
2. During execution
void main() {
int zero = 0;
IO.println(10 / zero);
}
This can compile because division is valid for integers. At runtime, dividing an integer by zero causes an exception.
3. The program runs but is wrong
void main() {
int width = 5;
int height = 4;
int area = width + height;
IO.println(area);
}
The code is legal. It runs. It prints 9. But the formula for rectangular area should multiply width and height. This is a logic error.
That third category is why a green Run button is weak evidence. Software can execute perfectly and still produce the wrong answer.
Trace the pipeline
For each case, identify the first stage where the problem becomes visible.
| Case | Source valid? | Compiles? | Begins execution? | Produces intended result? |
|---|---|---|---|---|
| missing closing brace | ? | ? | ? | ? |
| integer division by zero | ? | ? | ? | ? |
area = width + height | ? | ? | ? | ? |
| correct area formula | ? | ? | ? | ? |
Do not fill the table by guessing what the teacher wants. Explain one row using the source -> compiler -> JVM model.
Optional full-JDK evidence
If you have an approved Java 25 JDK environment, create Hello.java and compare these two workflows:
java Hello.java
and
javac Hello.java
java Hello
The first uses the source-code launcher. The second exposes compilation as a separate step.
Record what new file appears after javac. Do not submit a screenshot alone. Label what that file represents in the execution chain.
Evidence to keep
Create a one-page execution trace containing:
- one valid Java source snippet;
- an arrow diagram from source to observable output;
- one compile-time failure;
- one runtime failure;
- one logic error;
- one sentence explaining why "it ran" cannot prove correctness.
If you can classify those failures without relying on the exact error-message wording, you are already debugging at a more useful level than someone who only searches whatever red text appears first.