Аргументы командной строки: String[] args
Передаём данные в программу при запуске — как адреса на конвертах для почтальона
Что такое аргументы командной строки?
До этого урока наша функция main() всегда выглядела так:
public static void main(String[] args) {
// тело программы
}
Вы, наверное, замечали странный параметр String[] args и задавались вопросом: зачем он нужен? Сегодня мы наконец разберёмся!
args — это массив строк, который содержит данные, переданные программе при её запуске из командной строки (терминала). Это способ передать входные данные программе без перекомпилирования кода.
Аналогия: Представьте, что ваша программа — это ресторан. Когда вы запускаете программу без аргументов — это как прийти в ресторан и сказать «дайте что есть». А аргументы командной строки — это как сделать заказ: «дайте пасту, стакан воды и тирамису». Вы говорите кухне (программе), что именно приготовить (обработать).
Почему аргументы полезны?
- Гибкость — одна программа может работать с разными данными без изменения кода
- Удобство — можно быстро протестировать программу с разными входными данными
- Автоматизация — скрипты могут вызывать вашу программу с нужными параметрами
- Настройка — режим работы, формат вывода, путь к файлу — всё передаётся через аргументы
Как передать аргументы при запуске
Аргументы передаются после имени класса при запуске через терминал. Каждый аргумент разделяется пробелом:
java MyApp arg1 arg2 arg3
Если аргумент содержит пробелы, его нужно взять в кавычки:
java MyApp "Привет мир" "Иван Иванов"
Пример: Давайте создадим программу, которая выводит все переданные аргументы:
public class ShowArgs {
public static void main(String[] args) {
System.out.println("Количество аргументов: " + args.length);
for (int i = 0; i < args.length; i++) {
System.out.println("args[" + i + "] = " + args[i]);
}
}
}
Запуск и вывод:
$ java ShowArgs Привет мир 42
Количество аргументов: 3
args[0] = Привет
args[1] = мир
args[2] = 42
Запуск без аргументов:
$ java ShowArgs
Количество аргументов: 0
Обратите внимание: аргументы всегда являются строками (String). Даже число 42 передаётся как строка «42», а не как целое число. Это важно помнить!
Совет: В IDE (IntelliJ IDEA, Eclipse) аргументы командной строки можно задать в настройках запуска: Run → Edit Configurations → Program Arguments.
args — это обычный массив String
Поскольку args — это обычный массив строк, с ним можно работать точно так же, как с любым другим массивом String:
public class ArgsDemo {
public static void main(String[] args) {
// Длина массива
System.out.println("Аргументов: " + args.length);
// Доступ по индексу
if (args.length > 0) {
System.out.println("Первый: " + args[0]);
}
if (args.length > 1) {
System.out.println("Второй: " + args[1]);
}
// Последний аргумент
if (args.length > 0) {
System.out.println("Последний: " + args[args.length - 1]);
}
// Перебор всех аргументов
for (String arg : args) {
System.out.println("Аргумент: " + arg);
}
}
}
Все методы массивов работают:
public class ArgsMethods {
public static void main(String[] args) {
// Проверка на пустоту
if (args.length == 0) {
System.out.println("Аргументы не переданы!");
return;
}
// Цикл for с индексом
for (int i = 0; i < args.length; i++) {
System.out.println(i + ": " + args[i]);
}
// For-each
for (String arg : args) {
System.out.println(arg.toUpperCase());
}
}
}
Размер массива можно узнать через args.length (это поле, не метод!). Если аргументов нет — args.length равно 0, и попытка обратиться к args[0] вызовет ArrayIndexOutOfBoundsException.
Преобразование строк в числа
Все аргументы командной строки — это строки. Если вам нужно работать с числами, их необходимо преобразовать. Java предоставляет статические методы для этого:
Целые числа: Integer.parseInt()
public class ParseInt {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Передайте число!");
return;
}
int number = Integer.parseInt(args[0]);
System.out.println("Вы передали число: " + number);
System.out.println("Удвоенное: " + (number * 2));
}
}
Запуск:
$ java ParseInt 42
Вы передали число: 42
Удвоенное: 84
$ java ParseInt abc
Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"
Дробные числа: Double.parseDouble()
public class ParseDouble {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Передайте число!");
return;
}
double number = Double.parseDouble(args[0]);
System.out.println("Число: " + number);
System.out.println("Квадрат: " + (number * number));
}
}
Запуск:
$ java ParseDouble 3.14
Число: 3.14
Квадрат: 9.8596
Другие типы
long l = Long.parseLong("1234567890");
float f = Float.parseFloat("3.14");
boolean b = Boolean.parseBoolean("true");
byte by = Byte.parseByte("127");
short s = Short.parseShort("1000");
Важно: Методы парсинга выбрасывают NumberFormatException, если строка не является валидным числом. Всегда проверяйте данные или используйте try-catch.
Проверка количества аргументов
Перед использованием аргументов ОБЯЗАТЕЛЬНО проверяйте их количество. Если пользователь передал меньше аргументов, чем нужно — программа аварийно завершится с ошибкой. Это плохой пользовательский опыт.
public class Greeting {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Использование: java Greeting <имя>");
System.out.println("Пример: java Greeting Анна");
return;
}
System.out.println("Привет, " + args[0] + "!");
}
}
Проверка точного количества:
public class Add {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Нужно ровно 2 числа!");
System.out.println("Использование: java Add <число1> <число2>");
return;
}
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
System.out.println(a + " + " + b + " = " + (a + b));
}
}
Проверка минимального количества:
public class Sum {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Передайте хотя бы одно число!");
return;
}
int sum = 0;
for (String arg : args) {
sum += Integer.parseInt(arg);
}
System.out.println("Сумма: " + sum);
}
}
Шаблон проверки аргументов:
// Паттерн 1: Точный список
if (args.length != 3) {
System.out.println("Использование: java Program <a> <b> <c>");
return;
}
// Паттерн 2: Минимум
if (args.length < 2) {
System.out.println("Нужно минимум 2 аргумента!");
return;
}
// Паттерн 3: Опциональные аргументы
if (args.length == 0) {
// значения по умолчанию
} else if (args.length == 1) {
// один аргумент
} else {
// несколько аргументов
}
Совет: Всегда выводите справку по использованию программы, если аргументы переданы неверно. Это хороший тон и помогает пользователю понять, как правильно запустить программу.
Практический проект: Калькулятор
Давайте создадим простой калькулятор, который принимает три аргумента: два числа и операцию:
public class Calculator {
public static void main(String[] args) {
if (args.length != 3) {
System.out.println("Использование: java Calculator <число1> <операция> <число2>");
System.out.println("Операции: + - * /");
System.out.println("Пример: java Calculator 10 + 5");
return;
}
double a;
try {
a = Double.parseDouble(args[0]);
} catch (NumberFormatException e) {
System.out.println("Ошибка: '" + args[0] + "' не является числом!");
return;
}
String op = args[1];
double b;
try {
b = Double.parseDouble(args[2]);
} catch (NumberFormatException e) {
System.out.println("Ошибка: '" + args[2] + "' не является числом!");
return;
}
double result;
switch (op) {
case "+":
result = a + b;
break;
case "-":
result = a - b;
break;
case "*":
result = a * b;
break;
case "/":
if (b == 0) {
System.out.println("Ошибка: деление на ноль!");
return;
}
result = a / b;
break;
default:
System.out.println("Неизвестная операция: " + op);
System.out.println("Доступные операции: + - * /");
return;
}
System.out.println(a + " " + op + " " + b + " = " + result);
}
}
Примеры запуска:
$ java Calculator 10 + 5
10.0 + 5.0 = 15.0
$ java Calculator 20 / 4
20.0 / 4.0 = 5.0
$ java Calculator 7 * 3
7.0 * 3.0 = 21.0
$ java Calculator 10 / 0
Ошибка: деление на ноль!
$ java Calculator 10 x 5
Неизвестная операция: x
$ java Calculator 10 + 5 3
Использование: java Calculator <число1> <операция> <число2>
Этот пример демонстрирует несколько важных приёмов:
- Проверка количества аргументов
- Преобразование строк в числа с обработкой ошибок
- Валидация оператора через switch
- Проверка деления на ноль
- Информативные сообщения об ошибках
Другие практические примеры
Пример 1: Программа приветствия
public class Hello {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Привет, незнакомец!");
} else if (args.length == 1) {
System.out.println("Привет, " + args[0] + "!");
} else {
System.out.print("Привет");
for (int i = 0; i < args.length; i++) {
if (i > 0) {
System.out.print(", ");
}
System.out.print(args[i]);
}
System.out.println("!");
}
}
}
Пример 2: Конвертер температуры
public class TempConverter {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Использование: java TempConverter <температура> [C|F]");
System.out.println("По умолчанию: Цельсий → Фаренгейт");
return;
}
double temp = Double.parseDouble(args[0]);
String unit = args.length > 1 ? args[1].toUpperCase() : "C";
if (unit.equals("C")) {
double f = temp * 9.0 / 5.0 + 32;
System.out.printf("%.1f°C = %.1f°F%n", temp, f);
} else if (unit.equals("F")) {
double c = (temp - 32) * 5.0 / 9.0;
System.out.printf("%.1f°F = %.1f°C%n", temp, c);
} else {
System.out.println("Неизвестная единица: " + unit);
}
}
}
Пример 3: Поиск файла (упрощённый)
public class Find {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Использование: java Find <слово> [текст]");
return;
}
String word = args[0];
String text = args.length > 1 ? args[1] : "Java — отличный язык программирования";
int index = text.indexOf(word);
if (index != -1) {
System.out.println("Слово '" + word + "' найдено на позиции " + index);
} else {
System.out.println("Слово '" + word + "' не найдено");
}
}
}
Пример 4: Сумма чисел
public class SumNumbers {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Передайте числа через пробел!");
return;
}
double sum = 0;
int count = 0;
for (String arg : args) {
try {
sum += Double.parseDouble(arg);
count++;
} catch (NumberFormatException e) {
System.out.println("Пропущено: '" + arg + "' — не число");
}
}
if (count > 0) {
System.out.println("Сумма " + count + " чисел: " + sum);
System.out.println("Среднее: " + (sum / count));
} else {
System.out.println("Ни одно число не распознано!");
}
}
}
Пример 5: Генератор паролей
public class PasswordGen {
public static void main(String[] args) {
int length = 8;
if (args.length >= 1) {
try {
length = Integer.parseInt(args[0]);
if (length < 4 || length > 50) {
System.out.println("Длина должна быть от 4 до 50!");
return;
}
} catch (NumberFormatException e) {
System.out.println("Неверная длина: " + args[0]);
return;
}
}
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%";
StringBuilder password = new StringBuilder();
for (int i = 0; i < length; i++) {
int index = (int) (Math.random() * chars.length());
password.append(chars.charAt(index));
}
System.out.println("Пароль: " + password.toString());
}
}
Обработка ошибок при парсинге
При преобразовании строк в числа возможны ошибки. Есть два подхода к их обработке:
Подход 1: try-catch
public class SafeParse {
public static void main(String[] args) {
for (String arg : args) {
try {
int number = Integer.parseInt(arg);
System.out.println(arg + " → " + number);
} catch (NumberFormatException e) {
System.out.println(arg + " → ошибка: не число!");
}
}
}
}
Подход 2: Проверка регулярным выражением
public class RegexParse {
public static void main(String[] args) {
for (String arg : args) {
if (arg.matches("-?\\d+")) {
int number = Integer.parseInt(arg);
System.out.println(arg + " → " + number);
} else {
System.out.println(arg + " → не целое число");
}
}
}
}
Утилита безопасного парсинга
public class ParseUtil {
static int parseInt(String s, int defaultValue) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
return defaultValue;
}
}
static double parseDouble(String s, double defaultValue) {
try {
return Double.parseDouble(s);
} catch (NumberFormatException e) {
return defaultValue;
}
}
public static void main(String[] args) {
int port = parseInt(args.length > 0 ? args[0] : "", 8080);
double rate = parseDouble(args.length > 1 ? args[1] : "", 1.0);
System.out.println("Порт: " + port);
System.out.println("Ставка: " + rate);
}
}
Имя параметра args — произвольное
Параметр args в main() — это просто имя переменной. Вы можете назвать его как угодно:
public class AnyName {
public static void main(String[] arguments) {
System.out.println("Аргументов: " + arguments.length);
}
}
public class AnotherName {
public static void main(String[] argv) {
System.out.println("Аргументов: " + argv.length);
}
}
public class Params {
public static void main(String[] params) {
System.out.println("Аргументов: " + params.length);
}
}
Все эти варианты работают одинаково. Однако по конвенции в Java принято использовать args (от англ. «arguments»). Следуйте этой конвенции — другой программист сразу поймёт, что это аргументы командной строки.
Примечание: Если вы удалите параметр String[] args из main(), программа не скомпилируется. JVM требует именно этот сигнатуру для точки входа.
Практические задачи
Задача 1: Конвертер валют
public class CurrencyConverter {
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("Использование: java CurrencyConverter <сумма> <курс>");
System.out.println("Пример: java CurrencyConverter 100 92.5");
return;
}
try {
double amount = Double.parseDouble(args[0]);
double rate = Double.parseDouble(args[1]);
double result = amount * rate;
System.out.printf("%.2f USD = %.2f руб.%n", amount, result);
} catch (NumberFormatException e) {
System.out.println("Ошибка: неверный формат числа!");
}
}
}
Задача 2: Подсчёт слов
public class WordCounter {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Передайте слова через пробел!");
return;
}
int totalChars = 0;
for (String word : args) {
totalChars += word.length();
}
System.out.println("Слов: " + args.length);
System.out.println("Символов: " + totalChars);
System.out.println("Средняя длина слова: " + (double) totalChars / args.length);
}
}
Задача 3: Калькулятор площади
public class AreaCalculator {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Фигуры: circle, rectangle, triangle");
System.out.println("Использование: java AreaCalculator circle 5");
System.out.println(" java AreaCalculator rectangle 4 6");
System.out.println(" java AreaCalculator triangle 3 8");
return;
}
String figure = args[0].toLowerCase();
switch (figure) {
case "circle":
if (args.length < 2) { System.out.println("Нужен радиус!"); return; }
double r = Double.parseDouble(args[1]);
System.out.printf("Площадь круга: %.2f%n", Math.PI * r * r);
break;
case "rectangle":
if (args.length < 3) { System.out.println("Нужны ширина и высота!"); return; }
double w = Double.parseDouble(args[1]);
double h = Double.parseDouble(args[2]);
System.out.printf("Площадь прямоугольника: %.2f%n", w * h);
break;
case "triangle":
if (args.length < 3) { System.out.println("Нужны основание и высота!"); return; }
double base = Double.parseDouble(args[1]);
double height = Double.parseDouble(args[2]);
System.out.printf("Площадь треугольника: %.2f%n", base * height / 2);
break;
default:
System.out.println("Неизвестная фигура: " + figure);
}
}
}
Задача 4: Проверка возраста
public class AgeCheck {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Использование: java AgeCheck <возраст>");
return;
}
try {
int age = Integer.parseInt(args[0]);
if (age < 0) {
System.out.println("Возраст не может быть отрицательным!");
} else if (age < 14) {
System.out.println("Дети до 14 лет: " + age + " лет");
} else if (age < 18) {
System.out.println("Несовершеннолетние: " + age + " лет");
} else if (age < 65) {
System.out.println("Взрослые: " + age + " лет");
} else {
System.out.println("Пенсионеры: " + age + " лет");
}
} catch (NumberFormatException e) {
System.out.println("Введите целое число!");
}
}
}
Задача 5: Шифр Цезаря
public class CaesarCipher {
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("Использование: java CaesarCipher <текст> <сдвиг>");
return;
}
String text = args[0];
int shift = Integer.parseInt(args[1]);
StringBuilder result = new StringBuilder();
for (char c : text.toCharArray()) {
if (c >= 'A' && c <= 'Z') {
result.append((char) ('A' + (c - 'A' + shift) % 26));
} else if (c >= 'a' && c <= 'z') {
result.append((char) ('a' + (c - 'a' + shift) % 26));
} else {
result.append(c);
}
}
System.out.println("Шифр: " + result.toString());
}
}
Типичные ошибки
Ошибка 1: Доступ к args без проверки длины
public static void main(String[] args) {
// ❌ Если аргументов нет — ArrayIndexOutOfBoundsException!
System.out.println(args[0]);
// ✅ Правильно:
if (args.length > 0) {
System.out.println(args[0]);
}
}
Ошибка 2: Использование строки как число
// ❌ Строка + число = конкатенация
System.out.println(args[0] + 1); // "5" + 1 = "51"
// ✅ Сначала преобразуйте
int num = Integer.parseInt(args[0]);
System.out.println(num + 1); // 6
Ошибка 3: Забыть обработать NumberFormatException
// ❌ Если пользователь передаст "abc" — программа упадёт
int num = Integer.parseInt(args[0]);
// ✅ Оберните в try-catch
try {
int num = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
System.out.println("Это не число: " + args[0]);
}
Ошибка 4: Путаница пустой строки и отсутствия аргумента
java MyApp "" // args[0] = "" (пустая строка, аргумент ЕСТЬ)
java MyApp // args.length = 0 (аргументов НЕТ)
if (args.length == 0) {
// Это проверяет отсутствие аргументов
}
if (args[0].isEmpty()) {
// Это проверяет пустую строку
}
Паттерны использования аргументов командной строки
В реальных программах аргументы командной строки используются по определённым паттернам. Рассмотрим самые частые.
Паттерн 1: Флаги и значения
Многие командные утилиты используют флаги (опции) вида --flag значение или -f значение:
public class FlagParser {
public static void main(String[] args) {
String host = "localhost";
int port = 8080;
boolean verbose = false;
for (int i = 0; i < args.length; i++) {
switch (args[i]) {
case "--host":
case "-h":
if (i + 1 < args.length) host = args[++i];
break;
case "--port":
case "-p":
if (i + 1 < args.length) port = Integer.parseInt(args[++i]);
break;
case "--verbose":
case "-v":
verbose = true;
break;
}
}
System.out.println("Хост: " + host);
System.out.println("Порт: " + port);
System.out.println("Подробный режим: " + verbose);
}
}
// Запуск: java FlagParser --host 192.168.1.1 --port 3000 --verbose
Паттерн 2: Имя файла и опции
public class FileReader {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Использование: java FileReader <файл> [--lines|--words|--chars]");
return;
}
String filename = args[0];
String mode = args.length > 1 ? args[1] : "--lines";
System.out.println("Файл: " + filename);
System.out.println("Режим: " + mode);
// Здесь была бы реальная логика чтения файла
}
}
Паттерн 3: Позиционные аргументы
public class Deploy {
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("Использование: java Deploy <окружение> <версия> [флаги]");
System.out.println("Окружения: dev, staging, prod");
return;
}
String env = args[0];
String version = args[1];
boolean dryRun = false;
for (int i = 2; i < args.length; i++) {
if (args[i].equals("--dry-run")) {
dryRun = true;
}
}
System.out.println("Развёртывание " + version + " на " + env);
if (dryRun) {
System.out.println("(Пробный запуск — ничего не меняем)");
}
}
}
// Запуск: java Deploy prod 2.1.0 --dry-run
Паттерн 4: Значения по умолчанию
public class WebServer {
public static void main(String[] args) {
String host = "0.0.0.0";
int port = 80;
String root = "./public";
for (int i = 0; i < args.length; i += 2) {
if (i + 1 >= args.length) break;
switch (args[i]) {
case "--host": host = args[i + 1]; break;
case "--port": port = Integer.parseInt(args[i + 1]); break;
case "--root": root = args[i + 1]; break;
}
}
System.out.println("Сервер запускается на " + host + ":" + port);
System.out.println("Корневая директория: " + root);
}
}
// Запуск: java WebServer --port 3000
// Вывод: Сервер запускается на 0.0.0.0:3000
Совет: Для серьёзных проектов с множеством опций используйте специальные библиотеки для парсинга аргументов: Apache Commons CLI, Picocli, JCommander. Они автоматизируют валидацию, вывод справки и обработку ошибок.
Работа с аргументами в IDE
В реальной разработке вы редко запускаете программы из командной строки. Обычно это делается в IDE. Давайте разберём, как задать аргументы в популярных IDE.
IntelliJ IDEA
Откройте Run → Edit Configurations. В поле «Program arguments» введите аргументы через пробел. Например: 10 + 5. Аргументы применяются при каждом запуске программы.
Eclipse
Правой кнопкой по проекту → Run As → Run Configurations. На вкладке «Arguments» введите аргументы в поле «Program arguments». Каждый аргумент на новой строке или через пробел.
VS Code
В файле .vscode/launch.json добавьте поле "args" в конфигурацию запуска:
{
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Запуск",
"request": "launch",
"mainClass": "MyApp",
"args": ["10", "+", "5"]
}
]
}
Это полезно, потому что вы можете быстро менять аргументы без перекомпилирования кода. Просто меняете строку в настройках запуска — и программа получает новые данные.
Аргументы и безопасность
При работе с аргументами командной строки важно помнить о безопасности. Аргументы — это входные данные от пользователя, а входные данные всегда нужно проверять.
Правила безопасности:
- Никогда не используйте аргументы напрямую в SQL-запросах (SQL-инъекции)
- Не используйте аргументы как часть файлового пути без валидации (path traversal)
- Проверяйте длину строк — очень длинные аргументы могут вызвать переполнение буфера
- Проверяйте диапазоны чисел — отрицательные размеры, слишком большие значения
- Не доверяйте формату данных — пользователь может передать что угодно
public class SafeFileReader {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Использование: java SafeFileReader <имя_файла>");
return;
}
String filename = args[0];
// Проверка на path traversal
if (filename.contains("..") || filename.contains("/") || filename.contains("\\")) {
System.out.println("Ошибка: недопустимое имя файла!");
return;
}
// Проверка длины
if (filename.length() > 255) {
System.out.println("Ошибка: имя файла слишком длинное!");
return;
}
// Проверка на пустую строку
if (filename.trim().isEmpty()) {
System.out.println("Ошибка: имя файла не может быть пустым!");
return;
}
System.out.println("Чтение файла: " + filename);
}
}
Важно: Аргументы командной строки — это основной способ передачи параметров в утилиты и серверные программы. Правильная валидация аргументов — это часть хорошей инженерной практики.
Итоги урока
String[] argsв main() — это массив аргументов командной строки- Аргументы передаются через пробел при запуске:
java MyApp val1 val2 - Все аргументы — строки. Числа нужно преобразовывать через
Integer.parseInt(),Double.parseDouble() - Всегда проверяйте
args.lengthперед доступом к элементам - Обрабатывайте
NumberFormatExceptionпри парсинге чисел - Выводите справку по использованию при неверных аргументах
- Имя параметра можно менять, но по конвенции используют
args - Аргументы задаются в IDE через настройки запуска (Run Configurations)
- Проверяйте входные данные на безопасность: длину, формат, допустимые символы
Следующий урок: Vararg: переменное число аргументов
Тест: Аргументы командной строки
8 вопросов