Compiling and Running Java Programs
The Core Commands
Three commands form the basic Java workflow:
| Command | Purpose |
|---|---|
javac | Compile .java source files to .class bytecode files |
java | Launch the JVM and execute the bytecode in a .class file |
jshell | Interactive REPL for trying out Java code snippets |
javac — The Java Compiler
The javac command reads .java source files and produces .class bytecode files. The filename of a public class must match the filename: HelloWorld.java must define public class HelloWorld.
javac HelloWorld.java
This produces HelloWorld.class in the current directory. If the source file contains multiple classes (at most one public), javac produces one .class file per class.
Useful Flags
| Flag | Purpose |
|---|---|
-d <dir> | Specify output directory for .class files (default: same directory as source) |
-cp <path> or -classpath <path> | Specify where to find other .class files or JARs needed during compilation |
-sourcepath <path> | Where to find .java source files (default: current directory) |
-encoding <encoding> | Specify source file encoding (e.g. UTF-8) |
If your program depends on external libraries, you must tell javac where to find them. Assuming a library JAR at lib/utils.jar:
javac -cp lib/utils.jar:. src/MyProgram.java -d out/
The :. (or ;. on Windows) includes the current directory in the classpath so that previously compiled classes can be found.
java — The JVM Launcher
The java command starts the JVM and runs the main method of the specified class. Note: you provide the class name, not the filename — no .class extension.
java HelloWorld
The JVM loads the class, verifies the bytecode, and executes public static void main(String[] args).
Useful Flags
| Flag | Purpose |
|---|---|
-cp <path> or -classpath <path> | Where to find .class files and JARs at runtime |
-ea or -enableassertions | Enable assertions (off by default) |
-Xmx<size> | Set maximum heap size (e.g. -Xmx512m for 512 MB) |
-version | Print JVM version and exit |
Classpath at runtime works the same as at compile time:
java -cp lib/utils.jar:out/ MyProgram
jshell — The Interactive REPL
jshell, introduced in Java 9, provides a Read-Eval-Print Loop for interactive experimentation. It lets you write Java statements, expressions, and declarations without a full compile-build-run cycle. This is useful for exploring APIs, testing small code snippets, and learning the language.
jshell> int x = 42;
x ==> 42
jshell> x * 2
$2 ==> 84
jshell> String s = "Hello, " + x;
s ==> "Hello, 42"
jshell supports tab completion, forward references, and declaration redefinition. It uses a slightly relaxed syntax — semicolons are optional for top-level expressions. To exit, type /exit.
The Build-Run Cycle
A typical development workflow:
javac -d out/ src/HelloWorld.java
java -cp out/ HelloWorld
For a multi-file project:
javac -d out/ src/*.java
java -cp out/ MainClass
Or, if you are avoiding explicit compilation during experimentation:
java src/HelloWorld.java
Since Java 11, the java command can directly run a single source file — it compiles the file in memory and executes it. This is convenient for small scripts but does not produce persistent .class files.
Comparison with Python
Python does something similar under the hood:
| Java | Python (CPython) | |
|---|---|---|
| Source | .java | .py |
| Compiled to | .class bytecode | .pyc bytecode (cached in __pycache__/) |
| Execution engine | JVM | CPython VM (interpreter) |
| Compile step | Explicit (javac) | Implicit (automatic on import or first run) |
Both languages compile to a platform-independent bytecode and then execute it on a virtual machine. The key difference is that Python hides the compilation step — you rarely see .pyc files unless you look for them — while Java makes it an explicit part of the workflow.
Common Pitfalls
- Class name mismatch:
public class HelloWorldmust be in a file calledHelloWorld.java, and thejavacommand expects the class name, notHelloWorld.classorHelloWorld.java - Classpath issues: if your classes are in
out/, you must includeout/on the classpath when running - Forgetting to recompile: after editing a
.javafile, you must runjavacagain before runningjava— the JVM sees the.classfile, not the source - Case sensitivity:
helloworldandHelloWorldare different identifiers on all platforms (unlike Windows filenames)