W3docs

O método main do Java

O que significa public static void main(String[] args), por que cada modificador é obrigatório e como os argumentos de linha de comando são passados.

Toda aplicação Java começa dentro de um método com uma assinatura muito específica: public static void main(String[] args). A JVM procura por essa assinatura, a chama uma vez e o programa é executado até que essa chamada retorne (ou o programa seja encerrado de outra forma). Qualquer erro na assinatura e a JVM se recusa a iniciar o programa.

Você vem escrevendo essa linha em todos os exemplos desde o Hello World. Este capítulo a desmonta para que você saiba o que cada palavra faz e qual flexibilidade você tem.

A assinatura, palavra por palavra

public static void main(String[] args) { ... }
  • public — a JVM está "fora" da sua classe. Para chamar main de fora, ela precisa ser pública. Qualquer visibilidade mais restrita (private, package-private) e a JVM não consegue alcançá-la.
  • static — a JVM não constrói uma instância da sua classe primeiro; ela chama main na própria classe. Portanto, main deve pertencer à classe, que é o que static significa.
  • voidmain não retorna nada. O código de saída de um programa Java não é um valor de retorno; ele é definido com System.exit(...) ou assume o valor padrão 0 em uma conclusão limpa.
  • main — o nome literal que a JVM procura. Escreva Main, mian ou qualquer outra coisa e a JVM falha ao iniciar com Error: Main method not found in class ....
  • String[] args — um único parâmetro, um array de strings, contendo os argumentos da linha de comando. O nome do parâmetro não importa (args, argv, cmdline), apenas o tipo.

O array de parâmetros também pode ser escrito como varargsString... args — que é o mesmo tipo para a JVM e se comporta de forma idêntica:

public static void main(String... args) { ... }

Ambas as formas funcionam. A maioria do código usa String[] args por convenção.

Argumentos de linha de comando

Quando você executa um programa Java a partir do terminal, tudo após o nome da classe se torna elementos do array args:

$ java Greet Ada Lovelace

Dentro de Greet.main, args é {"Ada", "Lovelace"}:

public class Greet {
  public static void main(String[] args) {
    if (args.length == 0) {
      System.out.println("Hello, stranger");
    } else {
      System.out.println("Hello, " + String.join(" ", args));
    }
  }
}
  • args.length é o número de argumentos — 0 se nenhum foi fornecido.
  • Cada elemento é sempre uma String. Para usar um argumento numérico como número, faça o parse: int n = Integer.parseInt(args[0]);.
  • Aspas agrupam espaços no shell — java Foo "hello world" coloca um único elemento "hello world" em args.

O que não é permitido

A assinatura é fixa; pequenas variações compilam bem, mas falham na inicialização — a JVM exibe um Error: e sai antes que qualquer parte do seu código seja executada:

  • public void main(String[] args) — falta static. Error: Main method is not static in class ....
  • void main(String[] args) — falta public static. O mesmo erro "not static".
  • public static int main(String[] args) — tipo de retorno int. Error: Main method must return a value of type void in class ....
  • public static void Main(String[] args)M maiúsculo ou qualquer outro nome. Error: Main method not found in class ....
  • public static void main(String args) — tipo de parâmetro errado (uma única String, não um array). Error: Main method not found in class ....

Observe que esses são erros em tempo de execução, não erros de compilação — o javac aceita todos eles sem reclamar. A verificação ocorre quando o java tenta encontrar um ponto de entrada.

O que é permitido e não causa problemas:

  • final no parâmetro ou no método: public static final void main(final String[] args).
  • Cláusulas throws: public static void main(String[] args) throws Exception. Às vezes útil para experimentos rápidos.
  • Forma vararg: public static void main(String... args).

Várias classes, um único main

Cada classe pública de nível superior pode ter seu próprio main. Quando você executa java SomeClass, a JVM procura por main nessa classe. Assim, um projeto grande pode ter dezenas de classes com main para testes ou para pontos de entrada separados; apenas o que você nomeia na linha de comando é o ponto de entrada daquela execução.

// File Greet.java
public class Greet {
  public static void main(String[] args) { System.out.println("greet"); }
}

// File Sum.java
public class Sum {
  public static void main(String[] args) {
    int total = 0;
    for (String s : args) total += Integer.parseInt(s);
    System.out.println(total);
  }
}

java Greet executa o primeiro; java Sum 1 2 3 executa o segundo e exibe 6.

Encerrando um programa Java

main retornando normalmente encerra o programa com código de saída 0. Para sair antecipadamente ou definir um código de saída diferente de zero (sinalizando um erro para quem executou o programa), use System.exit:

if (args.length == 0) {
  System.err.println("usage: Sum <number>...");
  System.exit(1);
}

System.exit não retorna — ele encerra a JVM. Use-o com moderação; em bibliotecas, quase nunca é a ferramenta certa. Em um pequeno programa de linha de comando, é a forma padrão de sinalizar "não consegui fazer meu trabalho."

Um exemplo completo

java— editable, runs on the server

O que vem a seguir

Isso encerra a parte sobre métodos: você pode escrever métodos, passar parâmetros, sobrecarregá-los, usar recursão, variar a quantidade de argumentos e hospedar o ponto de entrada que comanda todo o programa. A próxima parte apresenta o container maior em que os métodos residem — classes e objetos — e o primeiro contato com o modelo orientado a objetos do Java.

Prática

Prática
Qual alteração em public static void main(String[] args) impede a JVM de executar o programa?
Qual alteração em public static void main(String[] args) impede a JVM de executar o programa?
Was this page helpful?