System properties
A map of strings the JVM keeps about its environment.
String home = System.getProperty("user.home");
String version = System.getProperty("java.version");
String sep = System.getProperty("file.separator");
getProperty returns null if the name is unknown. The two-argument form supplies a default:
String dir = System.getProperty("app.dir", "/tmp");
The useful ones
| Property | What it holds |
|---|---|
user.home |
the user’s home directory |
user.dir |
the current working directory |
user.name |
the account name |
java.version |
the running Java version |
os.name |
the operating system |
file.separator |
/ or \ |
line.separator |
the platform’s newline |
java.io.tmpdir |
the temporary directory |
Prefer the modern equivalents
Most of these have better replacements, and using them avoids assembling paths by hand:
Path home = Path.of(System.getProperty("user.home"));
Path config = home.resolve(".myapp").resolve("config.toml");
resolve inserts the right separator, so file.separator is rarely needed directly. Likewise System.lineSeparator() reads better than looking up line.separator, and String.format("%n") emits the platform newline without either.
Setting them
On the command line, before the class name:
java -Dapp.dir=/var/data -Denv=prod MyApp
Order matters. -D after the class name becomes a program argument instead.
At run time:
System.setProperty("app.dir", "/var/data");
This affects the whole JVM. Setting a property from library code is antisocial: it is global mutable state, and something else may depend on the old value.
Not application configuration
System properties are convenient and it is tempting to use them for everything. They are global, untyped strings with no namespace, and a typo produces null rather than an error.
For your own settings, a Properties file, an environment variable or a config file gives you a place to document defaults and something to validate at startup. Reserve -D for genuinely JVM-level switches and for overriding one value temporarily.
Environment variables
Different mechanism, different map:
String path = System.getenv("PATH");
Set outside the JVM, read-only from inside. Conventionally uppercase.
Listing everything
System.getProperties().forEach((k, v) -> System.out.println(k + " = " + v));
Useful once, when diagnosing an environment difference between two machines. Do not log the whole set routinely. It is long, and on some platforms it includes values you would rather not have in a log file.
Properties files
The related class, for your own configuration:
Properties props = new Properties();
try (var in = Files.newInputStream(path)) {
props.load(in);
}
String value = props.getProperty("key", "default");
The format is key=value, one per line, with # for comments. It reads as ISO-8859-1 unless you use the Reader overload, which is the usual cause of mangled non-ASCII values in older code.