1.1
Why Java Exists
See why Java was created and how one source file becomes instructions a computer can run.
Before you start
No previous programming required
You can begin here without knowing Java or another programming language.
Prerequisites
This is the first lesson. Its destination is precise: you should be able to explain why one compiled program may fail on another computer.
You will also explain how Java changed that distribution problem. Syntax comes later. This lesson builds the machine model that gives the syntax meaning.
Why this matters
Imagine that you write a program in a language such as C++. The file you edit is source code.
#include <iostream>
int main() {
std::cout << "Hello\n";
}A processor does not execute C++ source. A compiler translates the source into a native executable. That executable contains machine instructions and information expected by a particular platform.
For this lesson, a platform has two important parts:
| Processor architecture | Operating system | |
|---|---|---|
| Examples | x86-64, ARM64 | Windows, Linux, macOS |
| Contract | Instruction set and registers | Executable format and system services |
| What can differ | How to load, add, branch, and store | How programs open files, allocate memory, and display output |
Suppose you compile the program for Windows on x86-64. Copying that executable to macOS on ARM64 changes both parts of the platform.
The ARM64 processor does not use the same machine instructions as x86-64. macOS also uses different executable and operating-system conventions than Windows.
Even Windows and macOS on the same processor are different platforms. The processor instructions may match, but the operating-system contract does not.
This does not mean C++ source code cannot be portable. The same source can often be compiled for many targets. The distribution problem is about the compiled binary.
Traditional native distribution
- Write one source programHumans edit the same source files.
- Choose a target platformThe compiler and linker produce a native binary for that target.
- Repeat for other targetsEach supported processor and operating system needs a compatible build.
In the early 1990s, software was moving across a growing variety of computers and consumer devices. Rebuilding and testing every application for each target created a real delivery cost.
Core explanation
Java added a stable middle target between source code and the local machine.
Java source Java bytecode native execution
Hello.java -> Hello.class -> JVM for this platformThe Java compiler translates source into bytecode. Bytecode is an instruction format defined for the Java Virtual Machine, not for x86-64 or ARM64.
A Java Virtual Machine, or JVM, executes that bytecode. The JVM implementation knows how to work with its own processor and operating system.
Java distribution
- Write sourceThe programmer writes Hello.java.
- Compile to bytecodejavac creates Hello.class for the JVM instruction set.
- Distribute the class fileCompatible JVMs can load the same bytecode.
- Execute locallyEach JVM performs the platform-specific work on its machine.
The portable artifact is the bytecode. The JVM itself is not portable.
A Windows x86-64 JVM is a native Windows x86-64 program. A macOS ARM64 JVM is a different native program. Both implement the same JVM contract, so both can understand compatible class files.
That architecture is the basis of write once, run anywhere. The phrase is a design goal, not a guarantee that every program ignores its environment.
A Java program can still depend on platform-specific files, native libraries, fonts, permissions, or devices. Bytecode portability removes one major source of incompatibility. It does not erase all environmental differences.
Optional internals
Going deeperOpen optional internalsYou can finish the core lesson without this section.
Why processor architecture changes the binary
A processor implements an instruction set architecture, often shortened to ISA. The ISA defines operations that machine code may request.
It covers details such as instruction encoding, registers, memory access, arithmetic, and branches. x86-64 and ARM64 encode and organise those operations differently.
A sequence of bytes that means “load and add” to one architecture may mean something else to another. It may also be invalid there.
This is why a file containing native instructions has a processor target.
Why the operating system changes the binary
Programs need services outside pure arithmetic. They open files, create threads, request memory, read networks, and write to terminals.
The operating system defines how native programs request those services. It also defines executable formats, loading rules, libraries, and calling conventions.
The C++ line below looks independent of any operating system:
std::cout << "Hello\n";Its implementation eventually reaches platform-specific runtime and operating-system code. The source-level library hides that work, but the final native program must still fit the target system.
What the JVM standardises
The JVM supplies a virtual instruction set and a runtime model. Java class files describe code using that shared model.
The runtime then bridges to the real platform. Depending on the JVM and the code, it may interpret bytecode or compile selected methods into native instructions.
The important boundary is stable:
application bytecode
|
v
JVM implementation for this platform
|
v
processor and operating systemApplication teams target the upper contract. JVM teams implement the lower bridge.
Java had other design goals
Portability was not Java’s only goal. Its designers also removed or restricted several features that made large C++ programs harder to manage.
Java manages object memory with garbage collection. It does not expose pointer arithmetic in ordinary Java code. Class inheritance has one direct superclass, which avoids several multiple-inheritance conflicts.
Those choices do not make programming safe by default. They remove particular categories of error and make other checks possible.
Security also mattered. Early Java was associated with downloaded applets, which ran code from a network inside a browser.
That demanded verification and restricted execution. Browser applets are obsolete now, but bytecode verification and managed execution remain important parts of Java’s architecture.
Tradeoffs
The JVM adds a runtime layer. A Java application needs a compatible runtime, takes time to start, and uses memory for metadata and managed execution.
Garbage collection can also pause application work. Runtime compilation consumes CPU before it can improve frequently executed code.
Java accepted those costs to gain portable bytecode, automatic memory management, runtime checks, and adaptive optimisation. Whether that trade is useful depends on the program.
Check yourself
Answer from memory before opening the explanation. Then compare your rule with the answer and revisit the example if they differ.
What two parts make a computing platform in this lesson, and how can either part make a native binary incompatible?
Show the answer
A platform is the processor architecture plus the operating system. The processor accepts a particular instruction set. The operating system exposes its services through a particular binary interface. Change either contract and an existing native binary may no longer be valid.
What is the portable part of a Java program, and what part remains platform specific?
Show the answer
The compiled class files contain Java bytecode, which is designed for a JVM rather than one processor and operating system. The JVM remains platform specific because it must execute on the local processor and call the local operating system.
Did Java eliminate compilation for every platform?
Show the answer
No. It moved most platform-specific work into JVM implementations. An application developer can distribute the same compatible bytecode, while JVM builders provide a runtime for each supported platform.
Exercises
Start with the warm-ups. Continue to practice exercises when the basic idea works. Challenges are optional: skip them on a first pass and return after the next lesson.
- Warm up: one idea with close guidance.
- Practice: combine the idea with earlier material.
- Challenge: investigate an edge case or implementation detail.
4 exercises60 pointsabout 26 minutes
Trace the Journey
ex-1-1-aA Java program passes through two translators. Choose the sequence that puts the compiler, class file, JVM, and processor in their actual order.
Identify a Platform
ex-1-1-bA platform is the combination of a processor family and an operating system. Read the two command results and identify both parts.
Decide What Can Run
ex-1-1-cThe source machine used Intel and Windows. Select every target that has what the copied file needs to run unchanged.
Evaluate the Java Tradeoff
ex-1-1-dA sound technical recommendation states what improves and what the team still pays for. Select the claims that describe the trade honestly.
Where this leads
You now have the reason for the architecture. The next lesson names the runtime and development tools, then uses them on a real Java file.
Keep one diagram in your notes:
source -> javac -> bytecode -> JVM -> current platformLater connections
- Write once, run anywhereThe same promise is why you never free memory by hand.Phase XIII. Memory and the Garbage Collector
- CompilerYou run javac yourself and separate compilation from execution.1.2 - JVM, JRE, JDK, and Your First Program
Write once, run anywhere is next used in 1.2 - JVM, JRE, JDK, and Your First Program