Getting Started

Course 1 · Ch 1
Getting Started
The site's first compiled-to-bytecode language — a genuinely different model from C, C++, and Rust

Every language covered so far — C, C++, Rust — compiles source directly to native machine code, tied to one specific OS and CPU. Java does something structurally different, and this chapter is about that difference before anything else.

The JVM — A New Compilation Model

C, C++, and Rust all compile in one step: source → machine code, specific to the target platform. Java compiles to bytecode instead — an intermediate, platform-independent format — and the Java Virtual Machine (JVM) then interprets or compiles that bytecode to real machine code at runtime, on whatever platform it's actually running on. A genuinely different, two-stage model.

"Write Once, Run Anywhere"

The practical payoff: the exact same compiled .class bytecode file runs unmodified on Windows, Linux, or macOS, as long as each has its own JVM installed. Compare this against C/C++/Rust, where the source can be portable, but the compiled binary is not — recompiling separately for each target platform is required. Java shifts the portability boundary from source code to compiled bytecode.

javac and java

A two-command workflow: javac compiles .java source into .class bytecode; java then runs the JVM against that bytecode. Genuinely a two-step process, like c1-1's own compile-then-link model — but with a different split: not compile-then-link, but compile-then-run-on-a-VM.

$ javac Hello.java # produces Hello.class $ java Hello # runs it, via the JVM

JIT Compilation, Briefly

The JVM doesn't just interpret bytecode slowly forever. A Just-In-Time (JIT) compiler inside the JVM identifies "hot" code paths — the parts actually executed frequently — and compiles those specific parts to real machine code at runtime, for near-native performance where it matters most. A genuine, real engineering answer to "isn't interpreting bytecode slow?"

The Smallest Java Program

public class Hello { public static void main(String[] args) { System.out.println("Hello, Java!"); } }

A real, immediate ceremony worth naming directly: unlike C/C++'s free-standing main() function (c1-1, cpp1-1), Java requires every piece of code, even the entry point, to live inside a class. There is no such thing as a free function in Java at all — a genuinely different, stricter OOP-first philosophy from the very first line.

Compiling & Running

$ javac Hello.java $ java Hello Hello, Java!

A real, Java-specific compiler-enforced rule: the class name must match the filename exactly, for any public class.

ConceptC / C++ / RustJava
Compilation targetnative machine code, platform-specificbytecode, platform-independent
Portabilitysource portable, binary is notcompiled bytecode itself is portable
Entry pointa free-standing main() functionmust live inside a class — no free functions at all
File-to-class namingno relationship requiredpublic class name must match filename exactly
The filename rule is compiler-enforced, not a style guide
javac itself rejects a file where a public class's name doesn't match the filename — a real, immediate compile error, worth knowing from the very first program written.
Java's file organization is a structural requirement, not a convention
Unlike C's flexible file organization, Java's public-class-per-file rule (and matching filename) is enforced by the compiler in most cases — not merely a style preference a team could choose to ignore.

Coding Challenges

Challenge 1

Write a Java program in a file named Greeting.java with a public class Greeting whose main method prints two separate lines using two separate System.out.println calls. Compile and run it.

📄 View solution
Challenge 2

Deliberately name a file Wrong.java but declare the public class inside it as public class Right. Attempt to compile it with javac and report the exact error.

📄 View solution
Challenge 3

Explain, in your own words, why "write once, run anywhere" is a genuinely different claim than C's own "the source code is portable" — what specifically is portable in each case, and what still needs to happen on the target machine either way.

📄 View solution

Chapter 1 Quick Reference

  • Java compiles to bytecode, not native machine code — the JVM runs it at runtime, on any platform with a JVM installed
  • javac compiles .java.class; java runs the JVM against the compiled bytecode
  • The JIT compiler compiles "hot" bytecode paths to native code at runtime for near-native performance
  • Every piece of Java code lives inside a class — there are no free-standing functions, unlike C/C++
  • A public class's name must match its filename exactly — enforced by javac itself
  • Next chapter: variables and basic types — primitives vs. reference types, and boxing/unboxing