Linguagem Java ☕
Bem-vindo ao guia da linguagem Java, uma das linguagens de programação mais populares e versáteis do mundo. Famosa por sua filosofia “escreva uma vez, rode em qualquer lugar” (write once, run anywhere), o Java é fundamental para o desenvolvimento de aplicações web, mobile (Android), e sistemas de grande escala.
🛠️ Instalação e Configuração do Ambiente
Para desenvolver em Java, o primeiro passo é instalar o JDK (Java Development Kit), que é um pacote de software contendo o compilador e outras ferramentas essenciais.
-
Instale o Java JDK:
- Faça o download do OpenJDK 21 (LTS) a partir do site oficial da Oracle ou de uma distribuição como o Eclipse Temurin.
- Siga o instalador.
- Configure as Variáveis de Ambiente:
- Crie uma nova variável de ambiente
JAVA_HOMEapontando para a pasta de instalação do JDK (ex:C:\Program Files\Java\jdk-21). - Adicione o caminho da pasta
bindo JDK à variávelPathdo sistema (ex:%JAVA_HOME%\bin).
- Crie uma nova variável de ambiente
- Para verificar a instalação, abra um terminal e execute o comando
java -version.
-
Escolha uma IDE (Ambiente de Desenvolvimento Integrado): Enquanto o material original foca no Eclipse, as IDEs mais utilizadas atualmente para desenvolvimento Java são o VS Code e o IntelliJ IDEA.
Opção 1: VS Code
- Instale o Visual Studio Code.
- Na aba de extensões, instale o pacote “Extension Pack for Java” da Microsoft. Ele inclui tudo o que é necessário para compilar, executar e depurar código Java.
Opção 2: IntelliJ IDEA
- Baixe a versão Community (gratuita) do IntelliJ IDEA.
- O IntelliJ IDEA é altamente especializado para Java e oferece uma experiência de desenvolvimento muito produtiva, com ferramentas de análise de código e refatoração de ponta.
🚀 Seu Primeiro Programa em Java
Todo programa em Java é contido dentro de uma classe. A execução sempre começa no método main.
// É uma boa prática definir um pacote para organizar suas classes.
package curso;
// Declaração da classe principal.
public class Programa {
// Método principal, ponto de entrada do programa.
public static void main(String[] args) {
// Comando para imprimir uma linha no console.
System.out.println("Ola, Universo Java!");
}
}
📊 Tipos de Dados e Variáveis
Java possui tipos de dados primitivos para armazenar valores simples e tipos por referência (classes) para objetos complexos.
| Significado | Tipo em Java | Valor Padrão | Observação |
|---|---|---|---|
| Número Inteiro | int |
0 | O tipo padrão para inteiros. Use long para valores muito grandes. |
| Número de Ponto Flutuante | double |
0.0 | O tipo padrão para números reais. float oferece precisão simples. |
| Um Único Caractere | char |
'\u0000' |
Armazena um caractere Unicode, sempre entre aspas simples (ex: 'F'). |
| Texto | String |
null |
String é uma classe, não um tipo primitivo, e por isso começa com ‘S’ maiúsculo. Textos são declarados entre aspas duplas (ex: “Beatriz Costa”). |
| Valor Lógico | boolean |
false |
Aceita apenas os valores true ou false. |
📝 Declaração e Atribuição de Variáveis
A declaração de variáveis em Java exige a especificação de um tipo e um nome. A atribuição pode ser feita na mesma linha ou posteriormente.
package curso;
import java.util.Locale; // Importa a classe Locale para formatação.
public class Programa {
public static void main(String[] args) {
// Define o Locale para US para usar o ponto como separador decimal.
Locale.setDefault(Locale.US);
// Declaração e inicialização de variáveis.
int idade = 28;
double salario = 8200.50;
double altura = 1.65;
char genero = 'F';
String nome = "Beatriz Costa";
// Saída de dados.
System.out.println("NOME = " + nome);
System.out.println("IDADE = " + idade);
System.out.println("GENERO = " + genero);
// Usando String.format para formatar a saída com 2 casas decimais.
System.out.println("ALTURA = " + String.format("%.2f", altura));
System.out.println("SALARIO = " + String.format("%.2f", salario));
}
}
🔢 Operadores
Os operadores em Java são herdados de C/C++ e seguem a mesma lógica.
Aritméticos
| Operador | Significado |
|---|---|
+ |
Adição |
- |
Subtração |
* |
Multiplicação |
/ |
Divisão |
% |
Resto da divisão (“mod”) |
Comparativos
| Operador | Significado |
|---|---|
< |
Menor |
> |
Maior |
<= |
Menor ou igual |
>= |
Maior ou igual |
== |
Igual |
!= |
Diferente |
Lógicos
| Operador | Significado |
|---|---|
&& |
E |
|| |
OU |
! |
NÃO |
📥 Entrada de Dados com a Classe Scanner
Para ler dados do teclado em Java, utilizamos a classe Scanner, que deve ser importada da biblioteca java.util.
- Importe a classe:
import java.util.Scanner;. - Crie um objeto Scanner:
Scanner sc = new Scanner(System.in);. - Use os métodos de leitura:
nextInt(): Lê um número inteiro.nextDouble(): Lê um número double.next(): Lê a próxima palavra (até o espaço).nextLine(): Lê a linha inteira de texto.next().charAt(0): Lê uma palavra e pega apenas o primeiro caractere.
- Feche o Scanner:
sc.close();para liberar os recursos do sistema.
Atenção à Quebra de Linha Pendente:
Quando você lê um número (nextInt ou nextDouble), o cursor de leitura para após o número, deixando o “Enter” (
) no buffer de entrada. Se a próxima leitura for um nextLine(), ele lerá essa quebra de linha vazia.
Solução: Consuma a quebra de linha pendente com um sc.nextLine() extra antes de ler o texto.
package curso;
import java.util.Locale;
import java.util.Scanner;
public class Programa {
public static void main(String[] args) {
Locale.setDefault(Locale.US);
Scanner sc = new Scanner(System.in);
String nomeCompleto;
int idade;
double salario;
char genero;
System.out.print("Digite seu nome completo: ");
nomeCompleto = sc.nextLine();
System.out.print("Digite sua idade: ");
idade = sc.nextInt();
System.out.print("Digite seu salario: ");
salario = sc.nextDouble();
System.out.print("Digite seu genero (F/M): ");
genero = sc.next().charAt(0);
System.out.println("\n--- DADOS REGISTRADOS ---");
System.out.println("Nome: " + nomeCompleto);
System.out.println("Idade: " + idade);
System.out.println("Salario: " + String.format("%.2f", salario));
System.out.println("Genero: " + genero);
sc.close();
}
}
🔀 Estruturas de Controle
Estrutura Condicional (if-else)
Permite que o programa execute diferentes caminhos com base em condições.
// ... (dentro do método main)
Scanner sc = new Scanner(System.in);
System.out.print("Digite a hora atual (0-23): ");
int hora = sc.nextInt();
if (hora < 12) {
System.out.println("Bom dia!");
} else if (hora < 18) {
System.out.println("Boa tarde!");
} else {
System.out.println("Boa noite!");
}
sc.close();
Estrutura de Repetição while
O bloco de código é executado enquanto a condição for verdadeira.
// ... (dentro do método main)
Scanner sc = new Scanner(System.in);
int numero;
int soma = 0;
System.out.print("Digite um numero (0 para sair): ");
numero = sc.nextInt();
while (numero != 0) {
soma += numero;
System.out.print("Digite outro numero (0 para sair): ");
numero = sc.nextInt();
}
System.out.println("SOMA FINAL = " + soma);
sc.close();
Estrutura de Repetição for
Ideal para laços que precisam ser executados um número específico de vezes.
// ... (dentro do método main)
Scanner sc = new Scanner(System.in);
System.out.print("Quantos numeros serao somados? ");
int N = sc.nextInt();
int soma = 0;
for (int i = 0; i < N; i++) {
System.out.print("Digite o valor #" + (i + 1) + ": ");
int x = sc.nextInt();
soma += x;
}
System.out.println("SOMA = " + soma);
sc.close();
📏 Vetores e Matrizes
Vetores (Arrays)
Em Java, vetores são objetos que armazenam uma coleção de tamanho fixo de elementos do mesmo tipo.
// ... (dentro do método main)
Locale.setDefault(Locale.US);
Scanner sc = new Scanner(System.in);
System.out.print("Quantos numeros voce vai digitar? ");
int N = sc.nextInt();
// Declaração e instanciação do vetor
double[] vetor = new double[N];
for (int i = 0; i < N; i++) {
System.out.print("Digite um numero: ");
vetor[i] = sc.nextDouble();
}
System.out.println("\nNUMEROS DIGITADOS:");
for (int i = 0; i < N; i++) {
System.out.println(String.format("%.1f", vetor[i]));
}
sc.close();
Matrizes (Arrays Bidimensionais)
São vetores de vetores, úteis para representar dados em formato de tabela.
// ... (dentro do método main)
Scanner sc = new Scanner(System.in);
System.out.print("Quantas linhas tera a matriz? ");
int M = sc.nextInt();
System.out.print("Quantas colunas tera a matriz? ");
int N = sc.nextInt();
// Declaração e instanciação da matriz
int[][] matriz = new int[M][N];
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
System.out.print("Elemento [" + i + "," + j + "]: ");
matriz[i][j] = sc.nextInt();
}
}
System.out.println("\nMATRIZ DIGITADA:");
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
System.out.print(matriz[i][j] + " ");
}
System.out.println(); // Pula para a próxima linha
}
sc.close();
🐞 Depuração (Debugging) em Java
Depurar é o processo de encontrar e corrigir bugs no seu código. Tanto o VS Code quanto o IntelliJ IDEA possuem excelentes ferramentas de depuração visual. Os comandos do material original eram para o Eclipse.
Debugging no VS Code e IntelliJ IDEA
Os conceitos são os mesmos, apenas os atalhos podem variar.
- Habilitar/Desabilitar Breakpoint: Clique na margem à esquerda do número da linha onde você quer que a execução pause.
- Iniciar o Debug:
- IntelliJ: Pressione
Shift + F9ou clique no ícone de inseto ao lado da configuração de execução. - VS Code: Pressione
F5ou vá para a aba “Run and Debug” e inicie a sessão.
- IntelliJ: Pressione
- Controlar a Execução:
- Step Over (Passar por cima): Executa a linha atual e para na próxima. (F8 no IntelliJ, F10 no VS Code).
- Continue (Continuar): Continua a execução até o próximo breakpoint ou o fim do programa. (F9 no IntelliJ, F5 no VS Code).
- Inspecionar Variáveis: A aba “Debug” em ambas as IDEs mostrará uma janela “Variables” onde você pode ver e monitorar o valor das variáveis em tempo real.
🔀 Java em 3 Paradigmas: Resolvendo o Retângulo de Formas Diferentes
Um mesmo problema — calcular a área e o perímetro de um retângulo — resolvido de três formas bem diferentes. Este é o mesmo exercício que os Capítulos 11 (C), 05 (Python) e 30 (JavaScript) fazem em suas próprias linguagens.
🔁 Imperativo
Mesmo em Java, uma função “solta” (static) precisa morar dentro de uma classe — é uma regra da linguagem, não significa POO de verdade. É a versão imperativa disfarçada de Java.
import java.util.Locale;
import java.util.Scanner;
public class RetanguloImperativo {
public static double calcularArea(double base, double altura) {
return base * altura;
}
public static double calcularPerimetro(double base, double altura) {
return 2 * (base + altura);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
scanner.useLocale(Locale.US);
System.out.print("Digite a base do retângulo: ");
double base = scanner.nextDouble();
System.out.print("Digite a altura do retângulo: ");
double altura = scanner.nextDouble();
System.out.printf(Locale.US, "Area: %.2f%n", calcularArea(base, altura));
System.out.printf(Locale.US, "Perimetro: %.2f%n", calcularPerimetro(base, altura));
scanner.close();
}
}
🧬 Orientado a Objetos
Diferente da struct em C (Cap. 11), o private do Java é imposto pelo compilador: nenhum código fora da classe Retangulo pode ler ou alterar base/altura diretamente — só através dos métodos que a própria classe expõe. Isso é encapsulamento de verdade.
import java.util.Locale;
import java.util.Scanner;
class Retangulo {
private double base;
private double altura;
public Retangulo(double base, double altura) {
this.base = base;
this.altura = altura;
}
public double calcularArea() {
return base * altura;
}
public double calcularPerimetro() {
return 2 * (base + altura);
}
}
public class RetanguloPoo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
scanner.useLocale(Locale.US);
System.out.print("Digite a base do retângulo: ");
double base = scanner.nextDouble();
System.out.print("Digite a altura do retângulo: ");
double altura = scanner.nextDouble();
Retangulo meuRetangulo = new Retangulo(base, altura);
System.out.printf(Locale.US, "Area: %.2f%n", meuRetangulo.calcularArea());
System.out.printf(Locale.US, "Perimetro: %.2f%n", meuRetangulo.calcularPerimetro());
scanner.close();
}
}
🧩 Funcional
O Java moderno tem record (dado imutável por definição, sem setters) e a API de Streams, que processa coleções com .map() — o mesmo idioma funcional que você vê em Python e JavaScript.
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
import java.util.function.Function;
import java.util.stream.Collectors;
public class RetanguloFuncional {
record Retangulo(double base, double altura) {}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
scanner.useLocale(Locale.US);
System.out.println("--- Retângulo X ---");
System.out.print("Digite a base do retângulo X: ");
double baseX = scanner.nextDouble();
System.out.print("Digite a altura do retângulo X: ");
double alturaX = scanner.nextDouble();
System.out.println("--- Retângulo Y ---");
System.out.print("Digite a base do retângulo Y: ");
double baseY = scanner.nextDouble();
System.out.print("Digite a altura do retângulo Y: ");
double alturaY = scanner.nextDouble();
List<Retangulo> retangulos = List.of(
new Retangulo(baseX, alturaX),
new Retangulo(baseY, alturaY)
);
Function<Retangulo, Double> calcularArea = r -> r.base() * r.altura();
List<Double> areas = retangulos.stream()
.map(calcularArea)
.collect(Collectors.toList());
System.out.println(areas); // ex.: [24.0, 22.0]
scanner.close();
}
}
Repare o contraste com a versão POO acima: lá,
Retangulotinhaprivatee métodos que poderiam incluir setters. Aqui,recordé imutável por definição — nenhuma instância deRetangulopode mudar depois de criada, sem precisar de nenhuma palavra-chave extra.
🔗 Veja o mesmo problema em:
- 🔧 C — Capítulo 01 (seção “🔀 C em 3 Paradigmas”)
- 🐍 Python — Capítulo 09 (seção “🔀 Python em 3 Paradigmas”)
- ⚡ JavaScript — Capítulo 13 (seção “🔀 JavaScript em 3 Paradigmas”)