Visão geral da estrutura de um programa Java
Um programa Java é organizado em classes (tipos), que podem conter métodos (comportamentos) e atributos (dados). Para iniciar uma aplicação Java “tradicional” (linha de comando), a JVM procura um ponto de entrada específico: o método main. Além disso, o código costuma ser agrupado em pacotes para organizar responsabilidades e controlar visibilidade entre classes.
O que é uma classe
Uma classe é uma unidade de organização do código. Em Java, tudo o que você executa ou instancia está dentro de uma classe (mesmo que seja uma classe utilitária com métodos estáticos).
class Calculadora { int somar(int a, int b) { return a + b; }}Neste exemplo, Calculadora define um comportamento (somar) que pode ser usado por outras classes.
O método main como ponto de entrada
Para a JVM iniciar um programa, ela precisa encontrar um método com assinatura específica:
public static void main(String[] args)public: a JVM precisa acessar o método de fora da classe; se não forpublic, a JVM não consegue chamá-lo como ponto de entrada.static: permite chamar o método sem criar um objeto da classe.void: não retorna valor.String[] args: parâmetros de linha de comando.
public class App { public static void main(String[] args) { System.out.println("Olá, Java"); }}Pacotes: organização e identidade do código
Um pacote (package) agrupa classes relacionadas e define um “namespace” para evitar conflitos de nomes. O nome do pacote aparece no topo do arquivo:
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
package com.exemplo.app;O nome completo (qualificado) da classe passa a ser com.exemplo.app.App. Isso influencia diretamente como você compila e executa o programa.
Convenções de nomeação
- Pacotes: letras minúsculas, geralmente em formato reverso de domínio:
br.com.suaempresa.projeto. - Classes: PascalCase:
MinhaClasse,CalculadoraService. - Métodos e variáveis: camelCase:
calcularTotal,valorFinal. - Constantes: UPPER_SNAKE_CASE:
TAMANHO_MAXIMO.
Organização de arquivos e diretórios
Em Java, a estrutura de pastas deve refletir o pacote. Exemplo:
src/ com/ exemplo/ app/ App.java util/ Mensagens.javaO arquivo App.java deve começar com package com.exemplo.app; e Mensagens.java com package com.exemplo.util;.
Importações: como usar classes de outros pacotes
Quando você usa uma classe de outro pacote, pode referenciá-la pelo nome completo ou usar import.
Usando nome completo (sem import)
package com.exemplo.app; public class App { public static void main(String[] args) { com.exemplo.util.Mensagens.ola(); }}Usando import
package com.exemplo.app; import com.exemplo.util.Mensagens; public class App { public static void main(String[] args) { Mensagens.ola(); }}O import não “copia” código; ele apenas permite referenciar a classe sem escrever o nome completo.
Import estático (static import)
Útil para acessar membros estáticos sem prefixar o nome da classe (use com moderação para manter legibilidade):
package com.exemplo.app; import static com.exemplo.util.Mensagens.ola; public class App { public static void main(String[] args) { ola(); }}Visibilidade básica: public vs default (package-private)
Em Java, a ausência de modificador de acesso significa visibilidade padrão (também chamada de package-private): o membro/classe fica acessível apenas dentro do mesmo pacote.
Classe public vs classe com acesso padrão
package com.exemplo.util; public class Publica {}package com.exemplo.util; class SomenteNoPacote {}Publicapode ser usada por qualquer pacote (desde que esteja no classpath).SomenteNoPacotesó pode ser usada por classes dentro decom.exemplo.util.
Por que o main precisa ser public
O método main é chamado pela JVM, que está “fora” do seu pacote/classe. Se você escrever:
package com.exemplo.app; public class App { static void main(String[] args) { System.out.println("Não vai iniciar"); }}Ao tentar executar, a JVM não encontrará um ponto de entrada válido (porque o método não é public).
Passo a passo prático: criando múltiplas classes em pacotes diferentes
Objetivo
Criar uma aplicação com duas classes em pacotes diferentes e entender como package, import, visibilidade e classpath afetam compilação e execução.
1) Crie a estrutura de diretórios
projeto/ src/ com/ exemplo/ app/ App.java util/ Mensagens.java2) Escreva a classe utilitária
package com.exemplo.util; public class Mensagens { public static void ola() { System.out.println("Olá a partir do pacote util"); } }3) Escreva a classe com main
package com.exemplo.app; import com.exemplo.util.Mensagens; public class App { public static void main(String[] args) { Mensagens.ola(); } }4) Compile para uma pasta de saída (bin ou out)
Na pasta projeto, compile apontando a saída com -d:
javac -d out src/com/exemplo/util/Mensagens.java src/com/exemplo/app/App.javaIsso gera:
out/ com/ exemplo/ util/ Mensagens.class app/ App.class5) Execute informando o classpath
Ao executar, você informa onde estão os .class (raiz do classpath). Aqui é out:
java -cp out com.exemplo.app.AppNote que você executa pelo nome completo da classe (com.exemplo.app.App), não pelo caminho do arquivo.
Classpath na prática: como ele influencia a execução
O classpath é a lista de locais onde a JVM procura classes (pastas e/ou arquivos JAR). Se o classpath estiver errado, a JVM não encontra a classe principal ou dependências.
Erros comuns e o que significam
| Sintoma | Causa provável | Como corrigir |
|---|---|---|
Error: Could not find or load main class ... | Classpath não aponta para a raiz correta (ex.: apontou para out/com em vez de out) ou nome da classe está errado | Use -cp out e execute com.exemplo.app.App |
java.lang.NoClassDefFoundError | Classe foi encontrada em tempo de compilação, mas não está disponível em tempo de execução (faltou no classpath) | Inclua a pasta/JAR correto no -cp |
| Compila, mas não executa após mover arquivos | Pacote declarado não corresponde à estrutura de pastas | Garanta que package e diretórios coincidam |
Entendendo a “raiz” do classpath
Se a classe é com.exemplo.app.App, a JVM espera encontrar o arquivo em:
<algum_item_do_classpath>/com/exemplo/app/App.classPor isso, o item do classpath deve ser a pasta que contém com/ (no exemplo, out).
Atividades práticas (mão na massa)
Atividade 1: criar um pacote interno e testar visibilidade default
Crie no pacote com.exemplo.util uma classe com acesso padrão (sem public) e tente usá-la a partir de com.exemplo.app.
1) Crie:
package com.exemplo.util; class Segredo { static String mensagem() { return "visível apenas no pacote util"; } }2) Em App, tente:
package com.exemplo.app; import com.exemplo.util.Segredo; public class App { public static void main(String[] args) { System.out.println(Segredo.mensagem()); } }3) Observe o erro de compilação e explique: a classe Segredo não é public, então não pode ser acessada fora do pacote com.exemplo.util.
Atividade 2: duas classes com mesmo nome em pacotes diferentes
Crie duas classes Logger em pacotes distintos e use ambas na mesma classe.
1) Crie:
package com.exemplo.app; public class Logger { public static void log(String msg) { System.out.println("APP: " + msg); } }package com.exemplo.util; public class Logger { public static void log(String msg) { System.out.println("UTIL: " + msg); } }2) Em App, use o nome completo para evitar ambiguidade:
package com.exemplo.app; public class App { public static void main(String[] args) { com.exemplo.app.Logger.log("teste"); com.exemplo.util.Logger.log("teste"); } }Atividade 3: quebrando e corrigindo o classpath
1) Compile para out como antes. 2) Execute com classpath errado:
java -cp out/com com.exemplo.app.App3) Corrija para:
java -cp out com.exemplo.app.App4) Explique com suas palavras por que out é a raiz correta (ela contém a pasta com).