Java Argumentos da Linha de Comando
Desde o primeiro programa você escreve public static void main(String[] args). Agora dá para entender o String[] args: é um array de textos com as palavras que você escreve depois do nome do programa ao rodá-lo, como em java Main.java Ana 29. É outro jeito de dar informações ao programa, sem ele precisar perguntar.
- O que é o
argse como passar argumentos comjava Main.java …e comjava Main …. - Quantos argumentos chegaram:
args.length. - Argumentos com espaço (aspas) e o curinga
*do terminal. - Converter textos em números com
Integer.parseInteDouble.parseDouble. - Os erros reais:
ArrayIndexOutOfBoundsException(faltou argumento) eNumberFormatException(não é número). - Como escrever uma mensagem de uso, como os programas profissionais.
- Quando usar argumentos e quando usar o
Scanner.
Os exemplos rodam no terminal da Ana (máquina fictícia notebook, pasta ~/java, JDK 25).
A ideia antes do código
Há dois jeitos de pedir um café. No balcão, a atendente pergunta: "qual tamanho?", "com açúcar?", e você responde uma coisa de cada vez. Esse é o Scanner: o programa pergunta durante a execução. O outro jeito é entregar um bilhete já pronto: "café grande, sem açúcar". Ninguém precisa perguntar nada. Esses são os argumentos da linha de comando: você escreve tudo na mesma linha em que manda rodar o programa.
Você já usa isso o tempo todo no terminal. Em ls -l Documentos, o -l e o Documentos são argumentos do programa ls. Em javac Main.java, o Main.java é argumento do javac. Agora os seus programas também vão recebê-los.
Vendo o que chega no args
Este programa só mostra quantos argumentos recebeu e quais são:
public class Main {
public static void main(String[] args) {
System.out.println("Recebi " + args.length + " argumento(s)");
for (int i = 0; i < args.length; i++) {
System.out.println("args[" + i + "] = " + args[i]);
}
}
}
$ java Main.java Ana 29 Recebi 2 argumento(s) args[0] = Ana args[1] = 29 $ java Main.java Recebi 0 argumento(s) « sem argumentos, o array existe, mas está vazio
- java
- O lançador do Java.
- Main.java
- O programa a rodar. Não é um argumento do seu programa: é o que o
javavai executar. - Ana
- O primeiro argumento: vira
args[0]. - 29
- O segundo: vira
args[1]. Repare: é o texto"29", não o número.
O terminal corta a linha nos espaços e o Java coloca cada pedaço numa posição do array, na ordem. Tudo o que você já sabe de arrays vale aqui: args.length é a quantidade, args[0] é o primeiro, e os índices começam no 0.
args?
É a abreviação de arguments, "argumentos". É só um nome de variável: main(String[] parametros) também funciona. Mas args é a tradição, e todo programador Java reconhece.
Com javac e java separados
Se você compila antes (veja javac e java), os argumentos vêm depois do nome da classe:
$ javac Main.java $ java Main Ana 29 Recebi 2 argumento(s) args[0] = Ana args[1] = 29
No IntelliJ, no Eclipse e no VS Code, os argumentos ficam na configuração de execução, num campo chamado "Program arguments" (argumentos do programa). Veja Editores e IDEs. No editor do guia, a caixa de código pode trazer os argumentos prontos, como nas missões abaixo.
Argumentos com espaço: aspas
Como o terminal separa nos espaços, um nome completo viraria dois argumentos. As aspas juntam (é a mesma regra do Bash; veja o Guia Bash, aula de aspas):
$ java Main.java "Ana Souza" 29 Recebi 2 argumento(s) args[0] = Ana Souza « um argumento só, com o espaço dentro args[1] = 29 $ java Main.java 'R$ 10' 3,5 -v Recebi 3 argumento(s) args[0] = R$ 10 args[1] = 3,5 args[2] = -v
As aspas não chegam ao programa: elas são uma instrução para o terminal. E qualquer texto pode ser argumento, inclusive coisas como -v, que muitos programas usam como "opções".
O curinga *
Antes de rodar o programa, o terminal troca o * pelos nomes dos arquivos da pasta. Na pasta ~/java, só existe o Main.java:
$ java Main.java * Recebi 1 argumento(s) args[0] = Main.java « o * virou o nome do arquivo $ java Main.java 2 * 3 Recebi 3 argumento(s) args[0] = 2 args[1] = Main.java « era para ser o sinal de vezes! args[2] = 3
O seu programa nunca vê o *. Para mandar o caractere de verdade, proteja com aspas ('*') ou barra invertida (\*). Por isso, em calculadoras de linha de comando, é comum usar x para multiplicar.
Usar os argumentos: converter para número
Todo argumento é uma String. Para fazer contas, converta com Integer.parseInt ("interpretar como inteiro"):
public class Main {
public static void main(String[] args) {
String nome = args[0];
int idade = Integer.parseInt(args[1]);
System.out.println("Olá, " + nome + "! Daqui a 10 anos você terá " + (idade + 10) + " anos.");
}
}
$ java Main.java Ana 29 Olá, Ana! Daqui a 10 anos você terá 39 anos.
| Linha | O que faz |
|---|---|
String nome = args[0]; | O primeiro argumento já é texto: só copia para uma variável com um nome que explica o que ele é. |
int idade = Integer.parseInt(args[1]); | Transforma o texto "29" no número 29. Sem isso, args[1] + 10 daria "2910" (veja Concatenação). |
(idade + 10) | Agora é conta de verdade: 39. |
| Para obter | Use | Aceita |
|---|---|---|
int | Integer.parseInt(texto) | "29", "-3" |
long | Long.parseLong(texto) | "9000000000" |
double | Double.parseDouble(texto) | "7.5": sempre com ponto, qualquer que seja o idioma do computador |
boolean | Boolean.parseBoolean(texto) | "true" (qualquer outra coisa vira false) |
Essas classes (Integer, Double…) são os "wrappers" dos tipos primitivos e têm uma aula própria: Wrappers e Autoboxing.
Missão: o programa é rodado com os argumentos Ana 29. Complete as duas linhas para ele mostrar Olá, Ana! Você tem 29 anos., usando args[0] e convertendo args[1] com Integer.parseInt.
public class Main {
public static void main(String[] args) {
String nome = "?";
int idade = 0;
System.out.println("Olá, " + nome + "! Você tem " + idade + " anos.");
}
}
public class Main {
public static void main(String[] args) {
String nome = args[0];
int idade = Integer.parseInt(args[1]);
System.out.println("Olá, " + nome + "! Você tem " + idade + " anos.");
}
}
Quando falta argumento: ArrayIndexOutOfBoundsException
O mesmo programa, rodado sem argumentos, ou com um só:
$ java Main.java Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0 at Main.main(Main.java:3) $ echo $? 1 $ java Main.java Ana Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1 at Main.main(Main.java:4)
É a mesma exceção da aula de Arrays. Sem argumentos, o args tem tamanho 0 (length 0), e a linha 3 pediu o índice 0. Com um argumento só, o tamanho é 1, e a linha 4 pediu o índice 1. O código de saída 1 (que o echo $? mostra) indica que o programa terminou com erro.
Quando não é número: NumberFormatException
$ java Main.java Ana vinte Exception in thread "main" java.lang.NumberFormatException: For input string: "vinte" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) at java.base/java.lang.Integer.parseInt(Integer.java:565) at java.base/java.lang.Integer.parseInt(Integer.java:662) at Main.main(Main.java:4) $ java Main.java Ana 29.5 Exception in thread "main" java.lang.NumberFormatException: For input string: "29.5" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) at java.base/java.lang.Integer.parseInt(Integer.java:565) at java.base/java.lang.Integer.parseInt(Integer.java:662) at Main.main(Main.java:4)
- java.lang.NumberFormatException:
- "Exceção de formato de número": o texto não tem o formato de um número daquele tipo.
- For input string: "vinte"
- "Para o texto de entrada "vinte"": a mensagem mostra exatamente o que foi recebido, entre aspas. Muito útil para descobrir espaços ou caracteres escondidos.
- at java.base/…
- Três linhas de dentro do próprio Java (o
parseInttrabalhando). - at Main.main(Main.java:4)
- A linha do seu código que chamou o
parseInt. Comece sempre por ela.
"29.5" também falha: tem ponto, então não é um inteiro. Para decimais, use Double.parseDouble, que espera ponto: com "7,5" ele também lança NumberFormatException: For input string: "7,5" (conferido no laboratório).
A mensagem de uso
Programas de linha de comando bem-educados não explodem com uma exceção quando faltam argumentos: eles explicam como devem ser usados. Experimente javac sem nada: ele mostra como usá-lo. Vamos fazer o mesmo:
public class Main {
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Uso: java Main.java NOME IDADE");
System.err.println("Exemplo: java Main.java Ana 29");
System.exit(1);
}
String nome = args[0];
int idade = Integer.parseInt(args[1]);
System.out.println("Olá, " + nome + "! Daqui a 10 anos você terá " + (idade + 10) + " anos.");
}
}
$ java Main.java Uso: java Main.java NOME IDADE Exemplo: java Main.java Ana 29 $ echo $? 1 « 1 = terminou com erro $ java Main.java Ana 29 Olá, Ana! Daqui a 10 anos você terá 39 anos. $ echo $? 0 « 0 = tudo certo
| Linha | O que faz |
|---|---|
if (args.length != 2) | Confere a quantidade antes de usar qualquer args[i]. |
System.err.println(…) | Escreve na saída de erro (err = error), um canal separado da saída normal. No terminal, as duas aparecem iguais; mas quem redirecionar a saída para um arquivo (> resultado.txt) continua vendo o erro na tela. Veja print e println. |
Uso: … NOME IDADE | A convenção: a forma do comando, com as partes que o usuário troca em MAIÚSCULAS. Um exemplo concreto logo abaixo ajuda muito. |
System.exit(1); | Encerra o programa agora, com o código de saída 1. Por convenção, 0 é sucesso e qualquer outro número é erro. Sem esta linha, o programa continuaria e daria a exceção do mesmo jeito. |
Argumentos opcionais
Nem todo argumento precisa ser obrigatório. Se não vier nada, use um valor padrão:
public class Main {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Olá, visitante!");
} else {
System.out.println("Olá, " + args[0] + "!");
}
}
}
$ java Main.java Olá, visitante! $ java Main.java Ana Olá, Ana!
Quantos argumentos vierem: o for-each
Como args é um array, um for-each passa por todos, sejam quantos forem:
public class Main {
public static void main(String[] args) {
int soma = 0;
for (String arg : args) {
soma += Integer.parseInt(arg);
}
System.out.println("Soma: " + soma);
}
}
$ java Main.java 10 20 5 Soma: 35 $ java Main.java Soma: 0 « nenhuma volta: a soma ficou no valor inicial
Um exemplo completo: a calculadora
Três argumentos: número, operação, número. A escolha da operação usa o switch com setas:
public class Main {
public static void main(String[] args) {
double a = Double.parseDouble(args[0]);
String op = args[1];
double b = Double.parseDouble(args[2]);
double resultado = switch (op) {
case "+" -> a + b;
case "-" -> a - b;
case "x", "*" -> a * b;
case "/" -> a / b;
default -> {
System.err.println("Operação desconhecida: " + op);
System.exit(1);
yield 0;
}
};
System.out.println(a + " " + op + " " + b + " = " + resultado);
}
}
$ java Main.java 7 x 3 7.0 x 3.0 = 21.0 $ java Main.java 7.5 / 2 7.5 / 2.0 = 3.75 $ java Main.java 7 % 2 Operação desconhecida: % $ echo $? 1 $ java Main.java 7 * 3 Operação desconhecida: Main.java « o terminal trocou o * pelo nome do arquivo $ java Main.java 7 '*' 3 7.0 * 3.0 = 21.0
Para uma calculadora completa, com menu e validação, veja o projeto Calculadora.
Argumentos ou Scanner?
Argumentos (args) | Scanner | |
|---|---|---|
| Quando a informação chega | Antes de o programa começar, na linha do comando | Durante a execução, quando o programa pergunta |
| Tipo recebido | Sempre String (converter com parseInt…) | nextInt, nextDouble… já convertem |
| Ideal para | Ferramentas e scripts: rodar várias vezes com dados diferentes, automatizar | Programas conversando com uma pessoa: menus, jogos, cadastros |
| Separador decimal | Double.parseDouble: sempre ponto | nextDouble: o do idioma do computador (vírgula em pt_BR) |
| Erros comuns | ArrayIndexOutOfBoundsException, NumberFormatException | InputMismatchException, NoSuchElementException |
Muitos programas usam os dois: argumentos para as opções e o Scanner para conversar.
Quando dá errado
ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
O que aconteceu: o programa usou args[0], mas foi rodado sem argumentos (length 0). Também acontece quando você roda pela IDE e esquece de preencher "Program arguments".
Como resolver: passe os argumentos (java Main.java Ana 29) e, no código, confira args.length antes de usar, mostrando uma mensagem de uso.
NumberFormatException: For input string: "…"
O que aconteceu: o texto entre aspas na mensagem não é um número do tipo pedido: letras ("vinte"), decimal num parseInt ("29.5") ou vírgula num parseDouble ("7,5"). Também acontece quando os argumentos estão na ordem errada (java Main.java 29 Ana).
Como resolver: confira a ordem e o formato; para pegar o erro sem o programa parar, use try/catch (try e catch).
* virou nome de arquivo)
O que aconteceu: o terminal separa os argumentos nos espaços e expande os curingas (*, ?) antes de o Java receber qualquer coisa.
Como resolver: use aspas: "Ana Souza", '*'. Para conferir o que realmente chegou, rode o programa que lista os argumentos, do começo desta aula.
Com javac + java, os argumentos vêm depois do nome da classe (java Main Ana, sem .java). No modo arquivo-fonte, depois do arquivo (java Main.java Ana). Opções do próprio Java (como -Xmx256m) vêm antes do nome; tudo o que vier depois do nome vai para o seu args.
Referência
| Código ou comando | O que faz |
|---|---|
java Main.java a b c | Roda o arquivo-fonte com 3 argumentos |
java Main a b c | Roda a classe já compilada com 3 argumentos |
args.length | Quantidade de argumentos (0 se nenhum) |
args[0] | O primeiro argumento (sempre String) |
for (String arg : args) | Passa por todos |
Integer.parseInt(args[1]) | Converte para int (NumberFormatException se não der) |
Double.parseDouble(args[1]) | Converte para double (ponto decimal) |
System.err.println("Uso: …") | Mensagem de uso na saída de erro |
System.exit(1) | Encerra com código de erro |
"Ana Souza", '*' | No terminal: aspas protegem espaços e curingas |
Exercícios
1. Quantos?
Complete para mostrar quantos argumentos o programa recebeu:
2. Converter
Complete para transformar o terceiro argumento num int:
3. Rodar
Complete o comando para passar o nome Ana Souza como um argumento só:
4. Com java Main.java 5 8, quanto vale args[0] + args[1]?
5. Rodando java Main.java sem nada, quanto vale args.length?
6. Qual o papel do System.exit(1) depois da mensagem de uso?
Missão final: o programa recebe vários números como argumentos (no teste: 17 42 8 23) e deve mostrar o maior deles: Maior: 42. Converta cada argumento com Integer.parseInt e use a receita do maior de Percorrer Arrays. Se quiser ir além, mostre uma mensagem de uso quando não vier nenhum número.
public class Main {
public static void main(String[] args) {
// encontre o maior argumento aqui
int maior = 0;
System.out.println("Maior: " + maior);
}
}
public class Main {
public static void main(String[] args) {
if (args.length == 0) {
System.err.println("Uso: java Main.java NÚMERO...");
System.exit(1);
}
int maior = Integer.parseInt(args[0]);
for (String arg : args) {
int numero = Integer.parseInt(arg);
if (numero > maior) {
maior = numero;
}
}
System.out.println("Maior: " + maior);
}
}
Resumo
String[] argsé um array com as palavras escritas depois do nome do programa:java Main.java Ana 29→args[0] = "Ana",args[1] = "29".args.lengthdiz quantos vieram; sem argumentos, é 0 (o array existe, vazio).- Todo argumento é
String: converta comInteger.parseInt,Double.parseDouble(ponto decimal)… - Faltou argumento:
ArrayIndexOutOfBoundsException. Não é número:NumberFormatException: For input string: "…". - Confira
args.lengthprimeiro e mostre uma mensagem de uso comSystem.err+System.exit(1). - O terminal separa nos espaços e expande o
*antes do Java: use aspas.