Difficulty: Beginner | Prerequisites: None, though basic comfort with using a computer helps.
This material covers the foundation you need before writing any Java code: how source code becomes something a machine can run, the rules Java expects you to follow when writing that code, and how the computer stores the data your programs work with. These topics underpin every other unit in the course. If you are joining late, start here: everything from methods to object-oriented design assumes you already know what a compiler does, what a variable is, and how types work.
Java source code is compiled into platform-independent bytecode by javac, then interpreted at runtime by the JVM. Java enforces strict typing, meaning every variable must declare what kind of data it holds. Memory is split into primary (RAM), secondary (disk), and faster tiers (cache, registers), and Java stores objects like Strings on the heap.
Compiler
A tool that translates an entire high-level source file into machine code or bytecode before execution begins. In Java, the compiler is javac. It catches syntax errors and certain semantic errors during this translation step. In simple terms, the compiler reads your whole program, checks it for mistakes, and produces a runnable output file all at once.
Interpreter
A tool that executes source code (or bytecode) line by line, without producing a standalone executable. The JVM interprets Java bytecode at runtime; Python uses an interpreter directly on source code. Think of it as a translator who reads one sentence, speaks it aloud, then moves to the next, rather than translating the whole book first.
Bytecode
The intermediate, platform-independent instruction set that javac produces from Java source code. Bytecode runs on any machine that has a JVM installed, which is why Java is described as "write once, run anywhere."
JVM (Java Virtual Machine)
The runtime environment that interprets (and, in modern implementations, just-in-time compiles) Java bytecode on a specific operating system. The JVM is what makes Java platform-independent.
Syntax error
A mistake in the structure of your code that violates the language's grammar rules: missing semicolons, mismatched brackets, misspelled keywords. The compiler catches these before the program runs. In simple terms, your code broke a spelling or punctuation rule and Java refused to compile it.
Semantic error
A logical mistake where the code compiles and runs but produces the wrong result: an incorrect formula, using the wrong variable, dividing when you should multiply. The compiler cannot detect these. Think of it as writing a grammatically correct sentence that says the wrong thing.
Primitive type
One of Java's built-in, lightweight data types that stores a single value directly in memory: int, double, char, boolean. These are not objects.
Reference type
A data type that stores a reference (memory address) to an object on the heap rather than the value itself. Examples include String, arrays, and any user-defined class.
Immutable
Describes an object whose state cannot be changed after creation. Java Strings are immutable: every operation that appears to modify a String (concatenation, replace(), etc.) produces a new String object instead.
RAM (Random Access Memory)
The computer's primary memory, used for storing data and program instructions that are actively in use. It is fast but volatile (contents are lost when power is removed).
Heap memory
The region of memory where Java stores objects and Strings at runtime. Objects on the heap persist until the garbage collector reclaims them.
A compiler translates the entire source file before any code executes. Java's javac compiler converts .java files into .class files containing bytecode.
Compilers detect errors early: undeclared variables, type mismatches, missing semicolons, and invalid syntax are all caught at compile time.
An interpreter executes code statement by statement, without producing a separate executable. This makes debugging and testing more flexible but is typically slower.
Java uses both approaches: javac compiles source to bytecode, then the JVM interprets (and may JIT-compile) that bytecode at runtime.
Python, by contrast, is a primarily interpreted language, running source code through its interpreter directly.
Class names must match their filename. A class called MyClass must live in MyClass.java. This is a convention, not enforced by the compiler, but breaking it causes confusion.
Java is case-sensitive. myVariable and MyVariable are different identifiers.
Syntax errors are caught during compilation. Semantic errors surface at runtime or during testing, when the program runs but produces incorrect output.
Primary memory (RAM): fast, volatile, holds the data and instructions the CPU is actively working with.
Cache and registers: even faster and smaller than RAM, used by the CPU for immediate data access.
Secondary memory: hard drives, SSDs, CDs, DVDs. Slower but persistent, data survives a power cycle.
Primitive types store values directly: int (whole numbers), double (decimal numbers), char (single characters), boolean (true or false).
Reference types store a pointer to an object on the heap: String, arrays, and instances of any class you define.
Variables in Java are named memory locations. Every variable must be declared with a type before use: int count = 0;
Strings are stored on the heap and are immutable. Operations like concatenation create new String objects rather than modifying the original.
Java achieves platform independence through bytecode. Your .java source compiles to .class bytecode, and any machine with a JVM can run that bytecode.
This is the meaning of "write once, run anywhere."
The compiler-vs-interpreter distinction matters beyond exams. Production Java applications are compiled to bytecode and then further optimised by the JVM's just-in-time compiler at runtime, which is why Java performs well in server-side systems, Android apps, and large-scale enterprise software. Understanding memory tiers explains why caching strategies are central to building fast applications.
Students often think Java is purely compiled. It uses both compilation (source to bytecode) and interpretation (JVM running bytecode). The JVM's role is essential.
Students sometimes believe syntax errors and semantic errors are the same. Syntax errors prevent compilation entirely; semantic errors let the program compile and run, but it produces the wrong result.
"Immutable" does not mean you cannot reassign a String variable. You can point the variable at a new String object. What you cannot do is change the characters inside an existing String object.
Primary memory (RAM) and secondary memory (disk) are not interchangeable. RAM is fast and volatile; disk is slow and persistent.
⚠️ Know the difference between a compiler and an interpreter, and be able to explain where each is used in Java's execution pipeline.
⚠️ Be ready to classify an error as syntax, semantic, or runtime given a code snippet. This comes up frequently.
⚠️ Understand why Java is platform-independent (bytecode + JVM), and be able to state it in one sentence.
⚠️ Know the four primitive types (int, double, char, boolean) and that String is a reference type, not a primitive.
True or false: The JVM compiles Java source code into bytecode.
Fill in the blank: A _______ error is a logical mistake that the compiler cannot detect.
True or false: Java Strings can be modified after they are created.
Fill in the blank: RAM is an example of _______ memory.
True or false: char is a reference type in Java.
Answers: 1. False (javac does that; the JVM interprets bytecode). 2. Semantic. 3. False (Strings are immutable). 4. Primary. 5. False (it is a primitive type).
Q: What is the role of the javac compiler in Java's execution pipeline?
A: javac translates Java source code (.java files) into platform-independent bytecode (.class files). This bytecode is then executed by the JVM.
Q: A program compiles without errors but prints the wrong total. What type of error is this?
A: A semantic error. The code is syntactically valid, but the logic (e.g., a wrong formula or wrong variable) produces incorrect output.
Q: Why is Java described as platform-independent?
A: Java source code compiles to bytecode, which is not tied to any specific operating system or hardware. Any machine with a JVM can execute the bytecode, making Java portable across platforms.
Q: What is the difference between a primitive type and a reference type in Java?
A: A primitive type (e.g., int, boolean) stores its value directly in memory. A reference type (e.g., String, arrays) stores a reference (address) pointing to an object on the heap.
Q: Explain what it means for Strings to be immutable.
A: Once a String object is created, its character content cannot be changed. Any operation that appears to modify a String (such as concatenation or replace()) produces a new String object rather than altering the original.
This material connects directly to error handling and debugging (covered in later units), where the distinction between compile-time, runtime, and semantic errors becomes critical for fixing real programs. Understanding reference types and heap memory is the groundwork for the object-oriented programming unit, where every class instance is a reference type stored on the heap.
compiler, interpreter, javac, JVM, Java Virtual Machine, bytecode, platform independence, write once run anywhere, syntax error, semantic error, runtime error, primitive type, reference type, int, double, char, boolean, String, immutable, RAM, primary memory, secondary memory, cache, registers, heap memory, data types, variable declaration, CS 101, Texas A&M, CSCE, intro to programming