Java learning pathSection 1

Java Architecture Basics

Understand the Java platform, distinguish development tools from the runtime, and follow source code through compilation to portable bytecode and native execution.

1

The Java platform: tools, libraries, and execution

The Java platform is an environment for both developing and running applications. It combines development tools, standard class libraries, and a virtual machine. The language describes the program; the platform supplies the compiler, APIs, and runtime services that make it usable.

Java's object-oriented model organizes state and behavior into classes and objects. Its standard APIs support threads, networking, file access, and other common tasks, while the runtime provides services such as class loading, bytecode verification, and automatic memory management.

Portability, robustness, security mechanisms, and high performance are design goals rather than unconditional guarantees. Applications still need correct synchronization, sensible resource management, secure dependencies, and a compatible runtime.

  • Development: write, compile, inspect, debug, and package an application.
  • Runtime: provide the libraries and supporting files required by the application.
  • Execution: load and verify classes, execute instructions, and manage memory.
2

JDK vs JRE vs JVM

The Java Development Kit (JDK) supplies a runtime plus development utilities. The javac compiler translates Java source into class files; java launches applications; jar packages classes and resources; javadoc creates API documentation; and tools such as javap and jdb support inspection and debugging.

The Java Runtime Environment (JRE) is the runtime concept: a JVM, Java class libraries, and supporting configuration and native files. The JVM is the execution component within that environment, not a complete development kit or a replacement for the standard libraries.

The familiar JDK contains JRE contains JVM diagram is a useful responsibility model, not a promise about directories in every installation. Modern modular JDKs commonly have no separate jre directory, and standalone JRE availability depends on the distributor. A custom runtime image can contain just the modules an application needs.

JDK vs JRE vs JVM
ComponentPrimary jobCompiler included?Typical audience
JDKDevelop and run applicationsYes: javacDevelopers, build systems, and runtime operators
JRE / runtime imageRun applications with required librariesNot normallyDeployment environments
JVMExecute bytecode and provide runtime servicesNot the Java source compilerUsed indirectly by both
Nested responsibility map: the JDK adds development tools around a runtime containing libraries, supporting files, and the JVM.
Conceptual containment: development tools surround the runtime; the JVM is the execution core.
3

Follow a program from source to output

Start with Hello.java, which contains a class named Hello and its main method. Running javac Hello.java performs compilation and, when successful, produces Hello.class. The class file contains bytecode and structural information the JVM needs to understand the class.

Running java Hello asks the launcher to start a JVM and locate the Hello class. In this class-launch mode, use the class name rather than Hello.class. The JVM loads, links, and initializes classes as needed, then invokes main.

The execution engine runs the program using interpretation and, in a typical optimizing JVM, compiled native code. Library operations eventually interact with the operating system to display output. Class loading and compilation can continue during execution; this is not a one-time conveyor belt that finishes before all application work starts.

Compilation lane from Hello.java through javac to Hello.class, followed by a runtime lane for class loading, verification, interpretation or JIT compilation, and operating-system output.
javac produces portable class files; the installed runtime executes them on a particular machine.
Example
public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello, Java");
    }
}

// Save as Hello.java
// Compile: javac Hello.java
// Run:     java Hello
// Output:  Hello, Java
4

Platform independence has a boundary

Java normally distributes bytecode rather than an executable compiled for one CPU and operating system. The same compatible class file can run on Windows, Linux, and macOS because each platform provides its own JVM implementation of the bytecode contract.

The JVM and its native libraries are platform-specific. An application does not carry a magical platform-independent CPU instruction set; it carries instructions that a compatible runtime can interpret or compile into instructions for the local processor.

Compatibility also includes the class-file version and required APIs. A class built for a newer Java release cannot generally run on an older JVM. When targeting an older supported release, javac --release selects that release's language level, class-file target, and supported platform API surface.

One compatible class-file artifact branches to separate Windows, Linux, and macOS JVMs, each paired with its own operating system and CPU.
Portable artifact, platform-specific runtime. The Java release and application dependencies must also be compatible.
5

Write Once, Run Anywhere in practice

WORA describes writing an application once, compiling it into portable bytecode, and distributing that artifact to multiple compatible Java runtimes. It reduces the need to maintain a separate implementation and native build for each target operating system.

Using standard libraries helps preserve that benefit: a Java file API presents one application-facing contract even though the runtime uses different operating-system facilities underneath. A JAR can carry classes and resources without becoming tied to one processor architecture.

Portability must still be tested. Hard-coded path separators, case-sensitive filename assumptions, default encodings, time zones, platform-specific native libraries, and unavailable modules can all produce different results. WORA is not a promise that arbitrary environmental assumptions are portable.

6

Bytecode is an intermediate instruction format

Bytecode is the JVM instruction format generated by compilation. A .class file is more than a list of instructions: it also describes fields, methods, access flags, constants, and symbolic references to other classes and members.

Unlike machine code, bytecode is not directly executed as CPU instructions. An interpreter implements its behavior, while a just-in-time compiler can turn frequently executed methods or loops into native code. This separation lets the same artifact benefit from different runtime implementations and optimizations.

Verification checks structural and type-safety constraints before execution, including valid instruction operands and compatible operand-stack usage. It does not prove that the application has no bugs, that a downloaded library is trustworthy, or that native code is memory-safe.

Example
static int add(int a, int b) {
    return a + b;
}

// Inspect a compiled class with: javap -c Hello
// A simple static add method has instructions like:
// iload_0  -- load a
// iload_1  -- load b
// iadd     -- add the two int values
// ireturn  -- return the result
7

Compilation checks and runtime checks are different

javac parses source, resolves names and types, checks language rules, and emits class files. Syntax errors, incompatible assignments, inaccessible members, and many other invalid constructs are rejected before the application starts. Compilation does not establish that the business logic is correct.

A successful compilation may create several class files from one source file, for example when the source declares nested or additional classes. Class files can then be packaged into JARs together with resources for deployment.

At runtime, classes must still be found and linked against the environment actually installed. Missing dependencies, incompatible class versions, failed initialization, or changed library methods can prevent execution even when a previous build succeeded. Loading, verification, and execution have different responsibilities and different failure modes.

Compilation checks and runtime checks are different
StageExample problemWhat to inspect
Source compilationAssigning a String to an intCompiler message and source types
Class loading / linkingA required class is absent at runtimeClasspath or module path and dependency versions
ExecutionNull dereference or incorrect resultStack trace, input, and application logic
8

What the runtime supplies after compilation

The runtime supplies the JVM, standard class libraries, supporting native code, and configuration needed to execute the application. The java launcher starts the process and arranges the runtime environment; the JVM then coordinates class loading, execution, thread state, and managed memory.

For System.out.println, application code first uses the Java PrintStream API. The library and runtime eventually use platform-specific output facilities. The exact internal route varies by JDK and operation; not every library call must pass through a user-visible JNI method.

Automatic garbage collection reclaims unreachable managed objects, but it does not close every external resource or eliminate logical memory leaks. Close files and sockets appropriately, and avoid retaining objects in long-lived collections when they are no longer needed.