Atualizado: 16/08/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Arquivos compactos e método main em Java

A partir do JDK 21, foi introduzida, como recurso experimental, a possibilidade de criar arquivos compactos e métodos main simplificados, reduzindo a quantidade de código necessária para escrever programas Java. No JDK 25, esse recurso deixou de ser experimental e passou a estar disponível de forma estável.

O objetivo é simplificar tanto a estrutura do arquivo-fonte quanto a definição do método main. Com isso, é possível escrever programas sem declarar explicitamente uma classe e, ao mesmo tempo, usar um formato reduzido para o main.

Método main compacto

Tradicionalmente, um programa Java precisava seguir a seguinte estrutura, por exemplo, no arquivo Program.java:

public class Program {
    public static void main(String[] args) {
        System.out.println("Hello Programício!");
    }
}

Antes, para criar e executar um programa, era necessário:

  • Declarar uma classe (public class Program)
  • Criar um método main estático com parâmetro String[] args (public static void main(String[] args))

Com o novo recurso, é possível definir o main sem public static e sem o parâmetro String[] args:

class Program {
    void main() {
        System.out.println("Hello Programício!");
    }
}

Nas versões JDK 21, 22, 23 e 24, esse formato era experimental e exigia ativar o modo de pré-visualização ao compilar e executar. Por exemplo, no JDK 22:

javac --release 22 --enable-preview Program.java
java --enable-preview Program

A partir do JDK 25, essas opções adicionais não são mais necessárias:

javac Program.java
java Program
Hello Programício!

O processo de escolha e execução do método main funciona assim:

  • Se a classe definir ou herdar um método main com parâmetro String[], o Java Launcher seleciona esse método.
  • Caso contrário, se houver um método main sem parâmetros, ele será escolhido.
  • Se nenhum método adequado for encontrado, ocorre erro e a execução é encerrada.

Quando o método escolhido é estático, ele é chamado diretamente. Se for de instância, a classe precisa ter um construtor público ou de pacote, sem parâmetros. Nesse caso, o launcher cria uma instância e chama o método main nessa instância. Se esse construtor não existir, ocorre erro.

Exemplo com dois métodos main não estáticos:

public class Program {
    void main(String[] args) {
        System.out.println("With args");
    }

    void main() {
        System.out.println("Without args");
    }
}

Como existe uma versão com String[] args, ela será a escolhida para execução.

Arquivos compactos

Se o compilador encontrar campos e métodos no arquivo que não estejam dentro de uma declaração de classe, ele cria automaticamente uma classe de nível superior para conter esse conteúdo. Esse tipo de arquivo é chamado de arquivo-fonte compacto.

Antes, era obrigatório ter algo como:

public class Program {
    public static void main(String[] args) {
        System.out.println("Hello Programício!");
    }
}

Agora é possível escrever:

void main() {
    System.out.println("Hello Programício!");
}

Para arquivos compactos, o compilador gera implicitamente:

  • Uma classe no pacote não nomeado, estendendo java.lang.Object
  • Um construtor padrão sem parâmetros
  • Os campos e métodos declarados no arquivo como membros dessa classe
  • Um método main obrigatório; caso contrário, erro de compilação

Podemos incluir outros métodos e campos no arquivo, que também serão membros dessa classe implícita:

String sayHello() {
    return "Hello";
}

void main(String[] args) {
    System.out.println(sayHello());
}

Ou com campos:

String message = "Hello Work";

void main(String[] args) {
    System.out.println(message);
}

Como a classe é implícita, ela não possui um nome utilizável no código-fonte. O nome gerado pelo compilador é interno e não deve ser usado. Não é possível instanciá-la com new, mas é possível acessar o objeto atual com this.

Declarando outros tipos no mesmo arquivo

Podemos definir outros tipos, como classes, dentro do mesmo arquivo compacto:

void main(String[] args) {
    Person tom = new Person("Tom");
    System.out.println(tom.getName());
}

class Person {
    private String name;

    Person(String name) {
        this.name = name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
}

Nesse caso, Person se comporta como se estivesse declarada dentro da classe implícita do arquivo.

Se preferir, é possível declarar explicitamente uma classe para conter o main e deixar outros tipos fora dela:

class Program {
    void main(String[] args) {
        Person bob = new Person("Bob");
        System.out.println(bob.getName());
    }
}

class Person {
    private String name;

    Person(String name) {
        this.name = name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
}

Resumo

  • O JDK 25 tornou estáveis os arquivos compactos e o método main simplificado, antes experimentais no JDK 21 a 24.
  • É possível definir um método main sem public static e sem parâmetro String[] args.
  • Arquivos compactos permitem escrever código sem declarar explicitamente uma classe, gerando uma classe implícita automaticamente.
  • Esses arquivos podem conter campos, métodos e outros tipos, como classes internas ou externas ao main.
  • No JDK 25, não é necessário usar opções de pré-visualização para compilar e executar programas com essas funcionalidades.
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com