What actually makes Java platform independent, and where does the platform-specific part of the system really live?
Java is platform independent because your source is compiled into an intermediate bytecode format rather than into machine instructions for a particular processor and operating system. The compiler, javac, emits class files whose format is specified byte-for-byte by the Java Virtual Machine specification — the same on Windows, on Linux and on macOS. At runtime, the JVM on that machine interprets or JIT-compiles that bytecode into native instructions for the local CPU.
The platform-specific part therefore lives entirely inside the JVM implementation, which is a native component written in C++ and linked against the operating system. It is the JVM that knows how to open a socket, spawn a process or read a file. Your bytecode contains no such knowledge; it only contains calls into the Java class library, and the class library's native methods are the layer that ultimately calls into the operating system.
public class Main {
public static void main(String[] args) {
// The source contains no OS-specific calls at all.
// The platform knowledge lives in the JVM and the class library.
System.out.println("os.name : " + System.getProperty("os.name"));
System.out.println("os.arch : " + System.getProperty("os.arch"));
System.out.println("file.sep : " + System.getProperty("file.separator"));
System.out.println("line.sep : " + System.getProperty("line.separator").trim());
System.out.println("jvm : " + System.getProperty("java.vm.name"));
System.out.println("class file : CA FE BA BE (same bytes on every platform)");
}
}Two honest caveats. Portability is at the bytecode level, not the source level — the same bytecode runs everywhere, but the same source may not compile everywhere if it touches platform APIs. And the JVM itself is not portable: it is a native binary, so you still need a JVM build for each operating system and processor architecture you intend to support.