Leepoint Java Reference Notes on the Java language and its standard library.

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.