Introduction to Java
Java is a class-based, object-oriented, statically typed language designed to run the same compiled program on any machine with a compatible JVM.
Java is a general-purpose, class-based, object-oriented programming language first released by Sun Microsystems in 1995. It is statically typed (types are checked at compile time) and compiles to an intermediate form called bytecode, which runs on the Java Virtual Machine (JVM) rather than directly on any one operating system or CPU. This section introduces what Java is, why it was designed the way it was, and how it fits alongside languages like C, C++, and Python — without going deep into JVM internals, which are covered in their own later topics.
History and Origin
Java began in 1991 as a project at Sun Microsystems called 'Oak', led by James Gosling and a small team, originally targeting embedded consumer devices such as set-top boxes. The project was renamed Java and publicly released in 1995, repositioned for the exploding World Wide Web, where its promise of portable, safe, network-aware code was a strong fit for applets running inside browsers.
Sun Microsystems was acquired by Oracle Corporation in 2010, and Oracle has stewarded the Java Development Kit (JDK) and the Java Community Process (JCP) since. James Gosling is widely credited as the 'father of Java' for leading its original design and implementation.
Java's Design Goals
The original Java white paper described the language with a short list of goals, several of which still shape how the language evolves today:
Simple, object-oriented, and familiar (syntax deliberately close to C/C++) • Robust and secure (no explicit pointer arithmetic, mandatory bounds checking, strong compile-time type checking) • Architecture-neutral and portable (compile once, run anywhere a JVM exists) • High performance (bytecode designed to be efficiently interpreted and JIT-compiled) • Interpreted, threaded, and dynamic (supports multithreading and dynamic linking of classes at run time).
Class-Based, Object-Oriented, Statically Typed
Every piece of executable Java code lives inside a class (or, since Java 21, can live in an implicitly declared class for simple programs). 'Class-based' means objects are created from class blueprints, as opposed to prototype-based languages like JavaScript. 'Object-oriented' means Java organizes programs around objects that bundle data (fields) and behavior (methods), supporting encapsulation, inheritance, and polymorphism (covered in depth in the OOP topics).
'Statically typed' means every variable's type is known and checked at compile time, not discovered at run time. This catches many mistakes — such as calling a method that doesn't exist on a type — before the program ever runs, unlike dynamically typed languages such as Python or JavaScript.
The compiler rejects this program before it ever executes, because String cannot be assigned to an int variable.
int count = 5; // count is statically declared as int
count = "five"; // compile-time error: incompatible typesGeneral-Purpose Nature and Java Applications
Java is general-purpose: it is not restricted to one problem domain. In practice it is used for server-side web backends, Android mobile applications (via the Android SDK, which uses Java-like syntax and its own runtime), large enterprise systems, big-data tooling (Hadoop, Spark are written largely in Java/Scala on the JVM), desktop tools, and embedded/IoT devices.
Platform Independence: "Write Once, Run Anywhere"
Java source code (.java files) is compiled by javac into bytecode (.class files) — an intermediate, platform-neutral instruction format, not native machine code. Any machine with a compatible JVM installed can execute that same bytecode, regardless of the underlying operating system or CPU architecture. This is the essence of Java's famous slogan, 'Write Once, Run Anywhere' (WORA).
human-readable Java code interprets/JIT-compiles bytecode to native code
The same .class file runs unchanged on any operating system that has a matching JVM.
Portability applies to the compiled bytecode, not to every native library a program might call. Code that shells out to OS-specific commands or relies on OS-specific file paths is not automatically portable.
Java SE, Java EE/Jakarta EE, Java ME — Historical Context
Java is organized into editions. Java SE (Standard Edition) is the core language and libraries — what this course covers. Java EE (Enterprise Edition), covering web servers, servlets, and enterprise APIs, was donated by Oracle to the Eclipse Foundation and renamed Jakarta EE. Java ME (Micro Edition) targeted resource-constrained embedded and mobile devices and is largely legacy today, superseded by Android's own runtime for mobile.
Major Java Versions
Java has shipped many versions since 1996. A few milestones worth knowing by name:
Java 5 (2004): generics, enums, annotations, autoboxing • Java 8 (2014): lambda expressions, Streams, Optional — a major shift toward functional-style APIs • Java 9 (2017): the Java Platform Module System (JPMS) • Java 11 (2018): first Long-Term Support (LTS) release after the 6-month release cadence began • Java 17 (2021): LTS, sealed classes, pattern matching for switch (preview) • Java 21 (2023): LTS, virtual threads, record patterns, pattern matching for switch (final).
Since Java 9, a new feature release ships roughly every six months, but only certain releases (11, 17, 21, ...) are designated Long-Term Support and are what most production systems standardize on. This course targets a Java 17+ baseline unless a topic is explicitly about a version-gated feature.
Strengths and Limitations
Strengths: strong static typing catches many bugs early; automatic memory management removes a whole class of manual memory bugs; a huge, mature standard library and ecosystem; genuine cross-platform portability; strong tooling (IDEs, build tools, profilers).
Limitations: more verbose than many modern languages for small scripts; historically slower startup and higher memory footprint than compiled-to-native languages (something modern JVMs and AOT tools continue to improve); garbage collection introduces non-deterministic pause behavior that must be understood for latency-sensitive systems; no direct low-level memory/pointer control, which rules out some systems-programming use cases.
Java Terminology
JDK (Java Development Kit): tools to write and compile Java, including the compiler (javac) and the runtime. • JRE (Java Runtime Environment): the runtime needed to run Java programs (bundled inside the JDK in modern distributions). • JVM (Java Virtual Machine): the engine that executes bytecode. • Bytecode: the platform-neutral instruction set produced by javac. • Classpath: the set of locations the JVM searches for classes at run time.
Java Versus C/C++
Java's syntax is deliberately close to C/C++ (braces, semicolons, similar operators), which made it easy for C/C++ programmers to adopt in the 1990s. The major differences: Java has automatic garbage collection instead of manual memory management; Java has no pointer arithmetic and no direct pointers, only references; Java compiles to portable bytecode instead of native machine code per-platform; Java has no multiple inheritance of classes (only of interfaces); Java performs mandatory array bounds checking and enforces strict type safety at compile time.
Java Versus Python (High Level)
Python is dynamically typed and interpreted (types are checked and often resolved at run time), while Java is statically typed and compiled to bytecode ahead of execution. Python code tends to be more concise for small scripts; Java's static typing and tooling tend to pay off more as codebases and teams grow, catching whole categories of errors before the program ever runs. Both run on managed runtimes with automatic memory management, and both have vast ecosystems, but they solve different points on the trade-off between developer speed and compile-time safety.
First Simple Java Program
Every classic Java program's entry point is a method named main with a specific signature. Here is the traditional first program:
HelloWorld.java is compiled with javac HelloWorld.java to produce HelloWorld.class, then run with java HelloWorld, which prints the greeting to the console.
javac reads HelloWorld.java and produces HelloWorld.class (bytecode).
java HelloWorld starts a JVM, loads HelloWorld.class, and invokes its main method.
System.out.println writes the text followed by a newline to standard output.
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}Key Takeaways
Java is a class-based, object-oriented, statically typed, general-purpose language.
Source code compiles to platform-neutral bytecode, which any compatible JVM can run — this is 'write once, run anywhere.'
James Gosling led Java's original design at Sun Microsystems, released publicly in 1995; Oracle has stewarded it since acquiring Sun in 2010.
Java SE is the core language and libraries; Jakarta EE (formerly Java EE) covers enterprise/web APIs; Java ME targeted embedded devices historically.
Static typing and automatic memory management are Java's two biggest structural differences from C/C++; dynamic typing is Python's biggest structural difference from Java.
Java is an interpreted-only language, like early Python.
Java source compiles to bytecode, which the JVM typically interprets initially and then JIT-compiles hot code paths to native machine code.
Calling Java purely 'interpreted' ignores the JIT compilation step that gives Java much of its runtime performance.
Java and JavaScript are basically the same language with similar names.
Java and JavaScript are unrelated languages beyond a shared marketing-era name and superficially C-like syntax.
JavaScript is a dynamically typed scripting language standardized as ECMAScript; Java is a statically typed, compiled-to-bytecode language. The similar name was a 1995 marketing decision, not a technical relationship.
What does 'write once, run anywhere' actually refer to — the source code or the compiled output?
It refers to the compiled bytecode (.class files). The same bytecode runs unchanged on any machine with a compatible JVM, regardless of OS or CPU architecture.
Name two of Java's original design goals besides portability.
Any two of: simple/familiar (C-like syntax), object-oriented, robust and secure, architecture-neutral, high performance, interpreted/threaded/dynamic.
Is Java dynamically typed like Python? Why or why not?
No. Java is statically typed — every variable's type is fixed and checked by the compiler before the program runs, unlike Python where types are checked at run time.
What replaced Java EE, and under what organization?
Java EE was donated by Oracle to the Eclipse Foundation and renamed Jakarta EE.
Why might a team choose Java over Python for a large, long-lived enterprise codebase?
Java's static typing and compile-time checking catch many classes of bugs before the program runs, and its tooling and type information make large-team refactoring and IDE support stronger — trade-offs that tend to pay off more as codebase and team size grow.
What historical device category was the 'Oak' project (Java's precursor) originally targeting?
Embedded consumer devices, such as set-top boxes.
What guarantee does the JVM provide that raw compiled C/C++ machine code does not?
Portability of the compiled artifact (bytecode) across any operating system/CPU with a compatible JVM, plus mandatory array bounds checking and strong type safety enforced by the runtime.
Write a minimal Java program that prints your name to the console.
public class PrintName { public static void main(String[] args) { System.out.println("Ada Lovelace"); } }
The class name must match the file name (PrintName.java), and main must have exactly the signature public static void main(String[] args) to be recognized as the entry point.
What happens when this code is compiled?
It fails to compile with an 'incompatible types' error, because Java is statically typed: x was declared as int and a String cannot be assigned to it.
Name the two files produced/consumed when compiling and running HelloWorld.java, and the commands used.
javac HelloWorld.java // produces HelloWorld.class java HelloWorld // runs the class, loading HelloWorld.class javac compiles HelloWorld.java into HelloWorld.class (bytecode); java launches a JVM that loads HelloWorld.class and executes its main method.
int x = 10;
x = "ten";