«1. Введение

Пакет java.lang автоматически импортируется в приложение Java. Этот пакет содержит множество часто используемых классов от NullPointerException до Object, Math и String.

Класс java.lang.System является окончательным классом, что означает, что мы не можем создать его подкласс, поэтому все методы являются статическими.

Мы рассмотрим различия между двумя методами System для чтения системных свойств и переменных среды.

Это методы getProperty и getenv.

2. Использование System.getProperty()

Платформа Java использует объект Properties для предоставления информации о локальной системе и конфигурации, и мы называем его System Properties.

Системные свойства включают такую ​​информацию, как текущий пользователь, текущая версия среды выполнения Java и разделитель пути к имени файла.

В приведенном ниже коде мы используем System.getProperty(“log_dir”) для чтения значения свойства log_dir. Мы также используем параметр значения по умолчанию, поэтому, если свойство не существует, getProperty возвращает /tmp/log:

String log_dir = System.getProperty("log_dir","/tmp/log");

Чтобы обновить системные свойства во время выполнения, используйте метод System.setProperty:

System.setProperty("log_dir", "/tmp/log");

~ ~~ Мы можем передать наши собственные значения свойств или конфигураций в приложение, используя аргумент командной строки propertyName в формате:

java -jar jarName -DpropertyName=value

Установка свойства foo со значением bar в app.jar:

java -jar app -Dfoo="bar"

~~ ~ System.getProperty всегда возвращает строку.

3. Использование System.getenv()

Переменные среды представляют собой пары ключ/значение, как и свойства. Многие операционные системы используют переменные среды, чтобы разрешить передачу информации о конфигурации в приложения.

Способ установки переменной среды отличается от одной операционной системы к другой. Например, в Windows мы используем приложение System Utility из панели управления, а в Unix мы используем сценарии оболочки.

При создании процесса он по умолчанию наследует среду клонирования своего родительского процесса.

В следующем фрагменте кода показано использование лямбда-выражения для вывода всех переменных среды.

System.getenv().forEach((k, v) -> {
    System.out.println(k + ":" + v);
});

getenv() возвращает карту, доступную только для чтения. Попытка добавить значения на карту вызывает исключение UnsupportedOperationException.

Чтобы получить одну переменную, вызовите getenv с именем переменной:

String log_dir = System.getenv("log_dir");

С другой стороны, мы можем создать другой процесс из нашего приложения и добавить новые переменные в его среду.

Чтобы создать новый процесс в Java, мы используем класс ProcessBuilder, в котором есть метод, называемый окружением. Этот метод возвращает карту, но на этот раз карта не доступна только для чтения, то есть мы можем добавлять к ней элементы:

ProcessBuilder pb = new ProcessBuilder(args);
Map<String, String> env = pb.environment();
env.put("log_dir", "/tmp/log");
Process process = pb.start();

4. Различия

Хотя обе карты по сути являются картами, предоставляющими строковые значения для строковых ключей, давайте рассмотрим несколько отличий:

  1. We can update Properties at runtime while Environment Variables are an immutable copy of the Operating System’s variables.
  2. Properties are contained only within Java platform while Environment Variables are global at the Operating System level – available to all applications running on the same machine.
  3. Properties must exist when packaging the application but we can create Environment Variables on the Operating System at almost any point.

5. Заключение

Несмотря на концептуальное сходство, применение как свойств, так и переменных среды совершенно различно.

Выбор между вариантами часто зависит от масштаба. Используя переменные среды, одно и то же приложение можно развернуть на нескольких компьютерах для запуска разных экземпляров и настроить на уровне операционной системы или даже в консолях AWS или Azure. Устранение необходимости перестраивать приложение для обновления конфигурации.

Всегда помните, что getProperty следует соглашению о верблюжьем регистре, а getenv — нет.