Аргументы, окружение и код завершения
Программа редко живёт сама по себе: её запускают из терминала, скрипта или сервера, и ей нужно получить настройки — имя файла, режим работы, адрес базы данных. Для этого есть три способа: аргументы командной строки, переменные окружения и системные свойства. А в ответ программа сообщает, успешно ли она отработала, — кодом завершения.
Аргументы командной строки
Всё, что написано после имени файла в команде запуска, попадает в массив args — параметр метода main. В компактном файле его можно объявить: void main(String[] args). Аргументы разделяются пробелами, а значение с пробелом берут в кавычки:
void main(String[] args) {
IO.println("Аргументов: " + args.length);
for (String arg : args) {
IO.println(arg);
}
}Запуск:
java Main.java Анна "Олег Петров" 3Результат:
Аргументов: 3
Анна
Олег Петров
3Все аргументы — строки, даже 3. Число из них получают через Integer.parseInt(args[2]). В IntelliJ IDEA аргументы задают в настройках запуска: Run → Edit Configurations → Program arguments.
Переменные окружения
Переменные окружения — пары «имя = значение», которые операционная система передаёт каждой запущенной программе. В них обычно хранят то, что отличается на разных компьютерах: режим работы, адреса сервисов, пароли. System.getenv("ИМЯ") возвращает значение или null, если переменной нет:
void main() {
String mode = System.getenv("APP_MODE");
if (mode == null) {
mode = "разработка";
}
IO.println("Режим: " + mode);
}Запуск в bash (в PowerShell переменную задают так: $env:APP_MODE = "боевой"):
java Main.java
APP_MODE=боевой java Main.javaРезультат:
Режим: разработка
Режим: боевойСистемные свойства
Системные свойства — настройки самой JVM. Часть из них задана заранее: версия Java, имя операционной системы, домашняя папка пользователя. Свои свойства передают ключом -Dимя=значение — перед именем файла, иначе он станет обычным аргументом. Второй аргумент getProperty — значение по умолчанию:
void main() {
IO.println("Java " + System.getProperty("java.version"));
IO.println("Язык: " + System.getProperty("app.lang", "en"));
IO.println("Скидка: " + Integer.getInteger("app.discount", 0) + "%");
}Запуск:
java -Dapp.lang=ru -Dapp.discount=15 Main.javaРезультат (версия Java у вас может отличаться):
Java 25.0.4.1
Язык: ru
Скидка: 15%Integer.getInteger читает системное свойство сразу как число. Другие полезные свойства: user.home — домашняя папка, user.dir — текущая папка, os.name — операционная система.
Код завершения
Когда программа заканчивается, она возвращает операционной системе целое число — код завершения (exit code). 0 значит «успешно», любое другое число — «ошибка». Скрипты и серверы сборки смотрят на этот код, чтобы решить, продолжать ли работу. Задать его можно методом System.exit:
void main(String[] args) {
if (args.length == 0) {
System.err.println("Укажите имя файла");
System.exit(1);
}
IO.println("Обрабатываю " + args[0]);
}Запуск без аргумента и с ним; echo $? в bash показывает код завершения последней команды:
java Main.java
echo $?
java Main.java report.csv
echo $?Результат:
Укажите имя файла
1
Обрабатываю report.csv
0System.err — поток для сообщений об ошибках: в терминале он виден так же, как обычный вывод, но его можно перенаправить отдельно. System.exit останавливает JVM сразу — даже блоки finally не выполняются, поэтому вызывайте его только в самом конце, в main. Если программа завершилась необработанным исключением, код будет 1.
Частая ошибка
Программа берёт args[0], не проверив, что аргументы есть. Запуск без них заканчивается исключением:
void main(String[] args) {
String name = args[0];
IO.println("Привет, " + name + "!");
}Результат:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at Main.main(Main.java:2)Всегда проверяйте args.length и выводите подсказку, как запускать программу, — как в примере с кодом завершения.