Atualizado: 28/09/2025

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

Interação entre Módulos em Java: Exports e Requires

Aplicações Java complexas são frequentemente divididas em múltiplos módulos para melhorar a organização e a manutenção do código. Para que esses módulos possam colaborar, o Sistema de Módulos da Plataforma Java exige que a comunicação entre eles seja explícita. Este guia explica como fazer um módulo (o provedor) expor suas funcionalidades para que outro (o consumidor) possa utilizá-las.

O projeto de exemplo será composto por dois módulos distintos: operations e demo.

A estrutura de diretórios do projeto será a seguinte:

C:\java
├─── demo
│   ├─── com
│   │   └─── programicio
│   │       └─── hello
│   │           └─── Hello.java
│   └─── module-info.java
└─── operations
    ├─── com
    │   └─── programicio
    │       └─── factorial
    │           └─── Factorial.java
    └─── module-info.java

O Módulo Provedor: operations

Este módulo fornecerá uma funcionalidade de cálculo. Dentro do diretório operations/com/programicio/factorial, o arquivo Factorial.java é definido da seguinte forma:

package com.programicio.factorial;

public class Factorial {
    public static int calculate(int n) {
        if (n < 0) return -1;
        int result = 1;
        for (int i = 1; i <= n; i++) {
            result = result * i;
        }
        return result;
    }
}

Por padrão, o sistema de módulos impõe um encapsulamento forte: todos os pacotes são privados e inacessíveis de fora. Para permitir que outros módulos usem a classe Factorial, seu pacote deve ser exportado explicitamente.

Isso é feito no descritor do módulo, o arquivo operations/module-info.java:

module operations {
    exports com.programicio.factorial;
}

A diretiva exports torna todos os tipos públicos do pacote com.programicio.factorial visíveis para outros módulos que dependam de operations.

O Módulo Consumidor: demo

Agora, no módulo demo, é preciso declarar que ele irá consumir o módulo operations. Isso é feito no arquivo demo/module-info.java com a diretiva requires.

module demo {
    requires operations;
}

Com a dependência declarada e o pacote devidamente exportado pelo provedor, a classe Hello pode importar e utilizar a classe Factorial. O arquivo demo/com/programicio/hello/Hello.java terá o seguinte conteúdo:

package com.programicio.hello;

import com.programicio.factorial.Factorial;

public class Hello {
    public static void main(String[] args) {
        int a = 5;
        int b = Factorial.calculate(a);
        System.out.printf("Factorial of %d is equal to %d \n", a, b);
    }
}

Compilação e Execução

O processo deve seguir uma ordem lógica: primeiro compilamos o provedor (operations) e depois o consumidor (demo). Para manter o projeto organizado, os módulos compilados serão salvos em um diretório chamado appmodules.

Abra um terminal, navegue até o diretório c:\java e execute os comandos:

  1. Compilar o módulo operations: O comando salva os arquivos .class no diretório appmodules/operations.
  2. Compilar o módulo demo: A flag -p (--module-path) informa ao compilador onde encontrar o módulo operations do qual demo depende.
  3. Executar a aplicação: Novamente, a flag -p é usada para indicar onde encontrar todos os módulos necessários. A flag -m (--module) especifica a classe principal a ser executada.

A sessão completa no terminal ficará assim:

c:\java> javac -d appmodules/operations operations/module-info.java operations/com/programicio/factorial/Factorial.java

c:\java> javac -p appmodules -d appmodules/demo demo/module-info.java demo/com/programicio/hello/Hello.java

c:\java> java -p appmodules -m demo/com.programicio.hello.Hello
Factorial of 5 is equal to 120

c:\java>

Resumo

  • Encapsulamento Forte: Por padrão, todos os pacotes de um módulo são privados e inacessíveis a outros módulos.
  • Diretiva exports: Usada no módulo provedor para tornar um pacote público e visível para outros.
  • Diretiva requires: Usada no módulo consumidor para declarar que ele depende de outro módulo.
  • Compilação com -p: A flag --module-path (ou -p) é essencial para indicar ao compilador onde encontrar os módulos dependentes.
  • Execução com -p e -m: Para executar uma aplicação modular, é preciso especificar o caminho dos módulos (-p) e a classe principal a ser executada (-m).
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