☕
MANUAL COMPLETO DE
PROGRAMAÇÃO EM
JAVA
Do Básico ao Avançado
Versão 1.0 | Java SE 8 – 21
Abrange: Fundamentos • POO • Collections • Generics • Streams • Concorrência • Boas Práticas
Manual Completo de Programação em Java
1. Introdução ao Java
Java é uma linguagem de programação orientada a objetos, criada por James Gosling na
Sun Microsystems em 1995 e atualmente mantida pela Oracle. É uma das linguagens mais
populares do mundo, amplamente utilizada em desenvolvimento web, aplicações
empresariais, mobile (Android) e sistemas embarcados.
1.1 Por que Java?
Java oferece diversas vantagens que a tornam uma escolha sólida para desenvolvimento
de software:
• Write Once, Run Anywhere (WORA) — código compilado em bytecode executável
em qualquer JVM
• Fortemente tipada — reduz erros em tempo de execução
• Orientada a objetos — facilita organização, reutilização e manutenção do código
• Gerenciamento automático de memória — Garbage Collector
• Vasta comunidade e ecossistema de bibliotecas e frameworks
• Segurança — sandbox de execução e verificação de bytecode
1.2 Como o Java Funciona
O processo de execução de um programa Java envolve dois passos principais:
1. O código-fonte (.java) é compilado pelo javac para bytecode (.class)
2. A JVM (Java Virtual Machine) interpreta o bytecode e executa o programa
Código-fonte (.java)
↓ javac (compilador)
Bytecode (.class)
↓ JVM (Java Virtual Machine)
Execução no Sistema Operacional
💡 JDK vs JRE vs JVM
JVM (Java Virtual Machine): executa o bytecode. JRE (Java Runtime Environment): JVM +
bibliotecas de runtime. JDK (Java Development Kit): JRE + ferramentas de desenvolvimento
(javac, javadoc, etc.). Para desenvolver: instale o JDK.
1.3 Instalação e Configuração
Instalar o JDK
Acesse [Link] ou [Link] e instale o JDK 21 (LTS recomendado).
Página
Manual Completo de Programação em Java
Verificar a instalação
java -version
# Saída esperada:
# openjdk version "21.0.1" ...
javac -version
# Saída esperada:
# javac 21.0.1
IDEs Recomendadas
• IntelliJ IDEA (recomendada — Community Edition gratuita)
• Eclipse IDE
• VS Code com extensão Java Extension Pack
• NetBeans
1.4 Primeiro Programa: Hello World
// Arquivo: [Link]
public class HelloWorld {
public static void main(String[] args) {
[Link]("Olá, Mundo!");
}
}
Para compilar e executar no terminal:
javac [Link]
java HelloWorld
# Saída: Olá, Mundo!
💡 Estrutura básica
Todo programa Java precisa de uma classe com o mesmo nome do arquivo e um método
main(String[] args) como ponto de entrada.
Página
Manual Completo de Programação em Java
2. Sintaxe Básica
2.1 Comentários
// Comentário de linha única
/* Comentário
de múltiplas linhas */
/**
* Comentário Javadoc — para documentação
* @author Nome
* @version 1.0
*/
2.2 Tipos de Dados Primitivos
Tipo Tamanho Intervalo Padrão
byte 8 bits -128 a 127 0
short 16 bits -32.768 a 32.767 0
int 32 bits -2³¹ a 2³¹-1 0
long 64 bits -2⁶³ a 2⁶³-1 0L
float 32 bits ~3.4e-38 a ~3.4e+38 0.0f
double 64 bits ~1.7e-308 a ~1.7e+308 0.0d
char 16 bits \u0000 a \uFFFF '\u0000'
boolean 1 bit true ou false false
2.3 Declaração de Variáveis
// Declaração e inicialização
int idade = 25;
double salario = 3500.50;
char inicial = 'A';
boolean ativo = true;
String nome = "João"; // String é uma classe, não tipo primitivo
// var — inferência de tipo (Java 10+)
var contador = 0; // int
var mensagem = "Olá"; // String
// Constantes (final)
final double PI = 3.14159;
final int MAX_TENTATIVAS = 3;
Página
Manual Completo de Programação em Java
2.4 Operadores
Operadores Aritméticos
int a = 10, b = 3;
[Link](a + b); // 13 — adição
[Link](a - b); // 7 — subtração
[Link](a * b); // 30 — multiplicação
[Link](a / b); // 3 — divisão inteira
[Link](a % b); // 1 — módulo (resto)
// Incremento / Decremento
a++; // pós-incremento → a = 11
++a; // pré-incremento → a = 12
b--; // pós-decremento → b = 2
Operadores Relacionais e Lógicos
int x = 5, y = 10;
boolean result;
// Relacionais
result = (x == y); // false — igual
result = (x != y); // true — diferente
result = (x < y); // true — menor que
result = (x >= y); // false — maior ou igual
// Lógicos
result = (x < y) && (y > 0); // true — AND (e)
result = (x > y) || (y > 0); // true — OR (ou)
result = !(x == y); // true — NOT (negação)
// Ternário
String status = (x > 0) ? "positivo" : "não positivo";
2.5 Entrada e Saída
import [Link];
public class EntradaSaida {
public static void main(String[] args) {
Scanner scanner = new Scanner([Link]);
[Link]("Digite seu nome: ");
String nome = [Link]();
[Link]("Digite sua idade: ");
int idade = [Link]();
[Link]("Olá, %s! Você tem %d anos.%n", nome, idade);
Página
Manual Completo de Programação em Java
[Link]();
}
}
Página
Manual Completo de Programação em Java
3. Estruturas de Controle
3.1 Estrutura if / else
int nota = 75;
if (nota >= 90) {
[Link]("Aprovado com distinção");
} else if (nota >= 60) {
[Link]("Aprovado");
} else {
[Link]("Reprovado");
}
3.2 Switch
// Switch clássico
int dia = 3;
switch (dia) {
case 1: [Link]("Segunda"); break;
case 2: [Link]("Terça"); break;
case 3: [Link]("Quarta"); break;
default: [Link]("Outro dia");
}
// Switch expression (Java 14+) — mais conciso
String nomeDia = switch (dia) {
case 1 -> "Segunda";
case 2 -> "Terça";
case 3 -> "Quarta";
default -> "Desconhecido";
};
3.3 Laços de Repetição
for
// for clássico
for (int i = 0; i < 5; i++) {
[Link]("i = " + i);
}
// for-each (enhanced for)
int[] numeros = {1, 2, 3, 4, 5};
for (int num : numeros) {
[Link](num);
}
Página
Manual Completo de Programação em Java
while e do-while
// while — testa antes de executar
int i = 0;
while (i < 5) {
[Link](i);
i++;
}
// do-while — executa pelo menos uma vez
int j = 0;
do {
[Link](j);
j++;
} while (j < 5);
break e continue
for (int i = 0; i < 10; i++) {
if (i == 3) continue; // pula o 3
if (i == 7) break; // para no 7
[Link](i); // imprime 0,1,2,4,5,6
}
Página
Manual Completo de Programação em Java
4. Arrays
4.1 Arrays Unidimensionais
// Declaração e inicialização
int[] numeros = new int[5]; // 5 elementos, valor padrão 0
String[] nomes = {"Ana", "João", "Maria"}; // inicialização direta
// Acesso e modificação
numeros[0] = 10;
numeros[1] = 20;
[Link](numeros[0]); // 10
[Link]([Link]); // 3
// Percorrer com for-each
for (String nome : nomes) {
[Link](nome);
}
4.2 Arrays Multidimensionais
// Matriz 3x3
int[][] matriz = new int[3][3];
int[][] tabela = {{1,2,3}, {4,5,6}, {7,8,9}};
// Percorrer a matriz
for (int i = 0; i < [Link]; i++) {
for (int j = 0; j < tabela[i].length; j++) {
[Link]("%3d", tabela[i][j]);
}
[Link]();
}
4.3 Classe Arrays ([Link])
import [Link];
int[] arr = {5, 2, 8, 1, 9, 3};
[Link](arr); // ordena: {1,2,3,5,8,9}
[Link]([Link](arr)); // [1, 2, 3, 5, 8, 9]
int pos = [Link](arr, 5); // busca binária → retorna índice
int[] copia = [Link](arr, [Link]); // cópia completa
int[] parcial = [Link](arr, 1, 4); // cópia do índice 1 ao 3
[Link](arr, 0); // preenche tudo com 0
Página
Manual Completo de Programação em Java
Página
Manual Completo de Programação em Java
5. Programação Orientada a Objetos
Java foi construído em torno dos quatro pilares da Programação Orientada a Objetos
(POO): Encapsulamento, Herança, Polimorfismo e Abstração.
5.1 Classes e Objetos
// Definição de classe
public class Pessoa {
// Atributos (campos / fields)
private String nome;
private int idade;
private String cpf;
// Construtor padrão
public Pessoa() {}
// Construtor com parâmetros
public Pessoa(String nome, int idade, String cpf) {
[Link] = nome;
[Link] = idade;
[Link] = cpf;
}
// Getters e Setters
public String getNome() { return nome; }
public void setNome(String nome) { [Link] = nome; }
public int getIdade() { return idade; }
public void setIdade(int idade) {
if (idade >= 0) [Link] = idade;
}
// Método
public String apresentar() {
return [Link]("Olá! Sou %s, tenho %d anos.", nome, idade);
}
// toString — representação textual
@Override
public String toString() {
return "Pessoa{nome='" + nome + "', idade=" + idade + "}";
}
}
// Criação e uso de objetos
Pessoa p1 = new Pessoa("Ana", 30, "123.456.789-00");
[Link]([Link]());
[Link](p1); // chama toString()
5.2 Encapsulamento
O encapsulamento protege os dados internos da classe, expondo apenas o necessário
Página
Manual Completo de Programação em Java
através de métodos públicos (getters/setters).
public class ContaBancaria {
private double saldo; // privado — não acessível diretamente
private String titular;
public ContaBancaria(String titular, double saldoInicial) {
[Link] = titular;
[Link] = saldoInicial;
}
// Getter — apenas leitura
public double getSaldo() { return saldo; }
// Métodos com lógica de negócio
public void depositar(double valor) {
if (valor > 0) saldo += valor;
}
public boolean sacar(double valor) {
if (valor > 0 && valor <= saldo) {
saldo -= valor;
return true;
}
return false;
}
}
5.3 Herança
A herança permite que uma classe filha herde atributos e métodos de uma classe pai,
promovendo reutilização de código.
// Classe pai (superclasse)
public class Animal {
protected String nome;
protected String especie;
public Animal(String nome, String especie) {
[Link] = nome;
[Link] = especie;
}
public void comer() {
[Link](nome + " está comendo.");
}
public void fazerSom() {
[Link]("Som genérico");
}
}
// Classe filha (subclasse)
public class Cachorro extends Animal {
private String raca;
Página
Manual Completo de Programação em Java
public Cachorro(String nome, String raca) {
super(nome, "Canis lupus familiaris"); // chama construtor do pai
[Link] = raca;
}
@Override // sobrescrita do método
public void fazerSom() {
[Link](nome + " diz: Au Au!");
}
public void buscarBola() {
[Link](nome + " foi buscar a bola!");
}
}
// Uso
Cachorro dog = new Cachorro("Rex", "Labrador");
[Link](); // herdado de Animal
[Link](); // sobrescrito — Au Au!
[Link](); // próprio de Cachorro
5.4 Polimorfismo
// Polimorfismo — mesma referência, comportamentos diferentes
Animal[] animais = {
new Cachorro("Rex", "Labrador"),
new Gato("Mimi"), // supondo que existe a classe Gato
new Papagaio("Loro") // supondo que existe Papagaio
};
for (Animal a : animais) {
[Link](); // cada animal faz seu próprio som
}
// Verificação de tipo com instanceof
if (animais[0] instanceof Cachorro cachorro) { // pattern matching (Java 16+)
[Link]();
}
5.5 Classes Abstratas e Interfaces
Classe Abstrata
public abstract class Forma {
protected String cor;
public Forma(String cor) { [Link] = cor; }
// Método abstrato — subclasses devem implementar
public abstract double calcularArea();
public abstract double calcularPerimetro();
Página
Manual Completo de Programação em Java
// Método concreto — subclasses herdam
public void exibir() {
[Link]("Forma %s: área=%.2f%n", cor, calcularArea());
}
}
public class Circulo extends Forma {
private double raio;
public Circulo(String cor, double raio) {
super(cor);
[Link] = raio;
}
@Override
public double calcularArea() { return [Link] * raio * raio; }
@Override
public double calcularPerimetro() { return 2 * [Link] * raio; }
}
Interface
// Interface — contrato que classes devem cumprir
public interface Pagavel {
double calcularPagamento(); // método abstrato
default String status() { // método padrão (Java 8+)
return "Pagamento pendente";
}
}
public interface Descricao {
String getDescricao();
}
// Uma classe pode implementar múltiplas interfaces
public class Funcionario implements Pagavel, Descricao {
private String nome;
private double salarioBase;
public Funcionario(String nome, double salarioBase) {
[Link] = nome;
[Link] = salarioBase;
}
@Override
public double calcularPagamento() { return salarioBase; }
@Override
public String getDescricao() { return "Funcionário: " + nome; }
}
Característica Classe Abstrata Interface
Instanciação Não pode ser instanciada Não pode ser instanciada
Página
Manual Completo de Programação em Java
Herança/Implementação extends (uma só) implements (múltiplas)
Atributos Qualquer modificador public static final (constantes)
Métodos concretos Sim default e static (Java 8+)
Construtores Sim Não
Quando usar Base comum com estado Contrato/capacidades
Página
Manual Completo de Programação em Java
6. Tratamento de Exceções
O mecanismo de exceções do Java permite tratar situações anormais de forma estruturada,
sem quebrar o fluxo principal do programa.
6.1 Hierarquia de Exceções
Throwable
├── Error (erros graves — não tratar, ex: OutOfMemoryError)
└── Exception
├── RuntimeException (unchecked — não obrigatório tratar)
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ ├── NumberFormatException
│ └── IllegalArgumentException
└── IOException (checked — obrigatório tratar)
├── FileNotFoundException
└── SQLException
6.2 try-catch-finally
public class ExemploExcecao {
public static void main(String[] args) {
try {
int[] arr = new int[5];
arr[10] = 1; // lança ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
[Link]("Índice inválido: " + [Link]());
} catch (Exception e) {
[Link]("Erro genérico: " + [Link]());
} finally {
[Link]("Bloco finally — sempre executado");
}
}
}
6.3 try-with-resources
// Fecha automaticamente recursos que implementam AutoCloseable
try (var reader = new BufferedReader(new FileReader("[Link]"))) {
String linha;
while ((linha = [Link]()) != null) {
[Link](linha);
}
} catch (IOException e) {
Página
Manual Completo de Programação em Java
[Link]("Erro ao ler arquivo: " + [Link]());
}
// [Link]() é chamado automaticamente
6.4 Criando Exceções Personalizadas
// Exceção checked
public class SaldoInsuficienteException extends Exception {
private double saldoAtual;
public SaldoInsuficienteException(double saldoAtual, double valorSaque) {
super([Link]("Saldo insuficiente. Saldo: %.2f, Saque: %.2f",
saldoAtual, valorSaque));
[Link] = saldoAtual;
}
public double getSaldoAtual() { return saldoAtual; }
}
// Uso
public void sacar(double valor) throws SaldoInsuficienteException {
if (valor > saldo) {
throw new SaldoInsuficienteException(saldo, valor);
}
saldo -= valor;
}
Página
Manual Completo de Programação em Java
7. Collections Framework
O Java Collections Framework fornece um conjunto de interfaces e classes para trabalhar
com grupos de objetos de forma eficiente.
7.1 Principais Interfaces e Implementações
Interface Implementações Características
List ArrayList, LinkedList, Vector Ordenada, permite duplicatas, acesso por
índice
Set HashSet, LinkedHashSet, Sem duplicatas
TreeSet
Map HashMap, LinkedHashMap, Pares chave-valor, chaves únicas
TreeMap
Queue LinkedList, PriorityQueue FIFO — fila de processamento
Deque ArrayDeque, LinkedList Fila dupla (pilha e fila)
7.2 List (Lista)
import [Link].*;
// ArrayList — acesso rápido por índice, inserção/remoção lenta no meio
List<String> nomes = new ArrayList<>();
[Link]("Ana");
[Link]("João");
[Link](0, "Carlos"); // insere no índice 0
[Link]("João"); // remove por valor
[Link](0); // remove por índice
[Link]([Link](0)); // acesso por índice
[Link]([Link]()); // tamanho
[Link]([Link]("Ana")); // verificar existência
// Ordenação
[Link](nomes);
[Link]([Link]());
// Iteração
for (String nome : nomes) {
[Link](nome);
}
7.3 Map (Mapa)
Página
Manual Completo de Programação em Java
// HashMap — acesso O(1) por chave, sem ordenação
Map<String, Integer> notas = new HashMap<>();
[Link]("Ana", 85);
[Link]("João", 92);
[Link]("Maria", 78);
// Acesso
int notaAna = [Link]("Ana"); // 85
int nota = [Link]("Pedro", 0); // 0 se não existir
// Verificação
[Link]("João"); // true
[Link](92); // true
// Iteração
for ([Link]<String, Integer> entry : [Link]()) {
[Link]("%s: %d%n", [Link](), [Link]());
}
// Atualizar
[Link]("Ana", 90); // substitui
[Link]("Ana", 5, Integer::sum); // soma 5 ao valor atual
7.4 Set (Conjunto)
// HashSet — sem duplicatas, sem ordem
Set<String> frutas = new HashSet<>();
[Link]("Maçã");
[Link]("Banana");
[Link]("Maçã"); // ignorado — duplicata
[Link]([Link]()); // 2
// TreeSet — ordenado automaticamente
Set<Integer> numeros = new TreeSet<>([Link](5, 2, 8, 1, 9));
[Link](numeros); // [1, 2, 5, 8, 9]
// Operações de conjuntos
Set<Integer> a = new HashSet<>([Link](1, 2, 3, 4));
Set<Integer> b = new HashSet<>([Link](3, 4, 5, 6));
[Link](b); // interseção → {3, 4}
[Link](b); // diferença
[Link](b); // união
Página
Manual Completo de Programação em Java
8. Generics
Os Generics permitem criar classes, interfaces e métodos que trabalham com tipos
parametrizados, garantindo segurança de tipos em tempo de compilação.
8.1 Classe Genérica
// Classe genérica com tipo T
public class Caixa<T> {
private T conteudo;
public Caixa(T conteudo) { [Link] = conteudo; }
public T getConteudo() { return conteudo; }
public void setConteudo(T conteudo) { [Link] = conteudo; }
@Override
public String toString() { return "Caixa[" + conteudo + "]"; }
}
// Uso
Caixa<String> caixaTexto = new Caixa<>("Olá");
Caixa<Integer> caixaNum = new Caixa<>(42);
String texto = [Link](); // sem cast necessário
int num = [Link]();
8.2 Método Genérico
public class Utilitarios {
// Método genérico
public static <T extends Comparable<T>> T maior(T a, T b) {
return [Link](b) >= 0 ? a : b;
}
// Com múltiplos tipos
public static <K, V> Map<V, K> inverter(Map<K, V> mapa) {
Map<V, K> resultado = new HashMap<>();
[Link]((k, v) -> [Link](v, k));
return resultado;
}
}
// Uso
[Link]([Link](10, 20)); // 20
[Link]([Link]("Ana", "João")); // João
8.3 Wildcards (?)
Página
Manual Completo de Programação em Java
// Wildcard ilimitado — aceita qualquer tipo
public static void imprimirLista(List<?> lista) {
[Link]([Link]::println);
}
// Bounded wildcard — aceita Number e subtipos (Integer, Double...)
public static double somar(List<? extends Number> lista) {
return [Link]().mapToDouble(Number::doubleValue).sum();
}
// Lower bounded — aceita Integer e supertipos
public static void adicionarNumeros(List<? super Integer> lista) {
[Link](1);
[Link](2);
}
Página
Manual Completo de Programação em Java
9. Streams e Expressões Lambda (Java 8+)
Introduzidos no Java 8, Streams e Lambdas permitem programar de forma funcional e
expressiva, facilitando operações sobre coleções de dados.
9.1 Expressões Lambda
// Sintaxe: (parâmetros) -> { corpo }
// Sem parâmetros
Runnable r = () -> [Link]("Executando!");
// Com parâmetros
Comparator<String> comp = (a, b) -> [Link](b);
// Com tipo inferido e retorno direto
Function<Integer, Integer> dobro = x -> x * 2;
// Com bloco
Function<String, String> processar = s -> {
String resultado = [Link]().toLowerCase();
return resultado;
};
// Uso em Collections
List<String> nomes = [Link]("Ana", "João", "Maria");
[Link](nome -> [Link](nome));
[Link]((a, b) -> [Link](b));
9.2 Method References
// Referência a método estático: Classe::metodo
[Link]([Link]::println);
// Referência a método de instância: instancia::metodo
String prefixo = "Sr. ";
[Link]().map(prefixo::concat).forEach([Link]::println);
// Referência a construtor: Classe::new
List<Pessoa> pessoas = [Link]()
.map(Pessoa::new) // chama new Pessoa(nome)
.collect([Link]());
9.3 Streams API
import [Link].*;
Página
Manual Completo de Programação em Java
List<Integer> numeros = [Link](1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// filter — filtrar
List<Integer> pares = [Link]()
.filter(n -> n % 2 == 0)
.collect([Link]()); // [2,4,6,8,10]
// map — transformar
List<Integer> dobrados = [Link]()
.map(n -> n * 2)
.collect([Link]()); // [2,4,6,8,10,12,14,16,18,20]
// reduce — acumular
int soma = [Link]()
.reduce(0, Integer::sum); // 55
// Encadeamento de operações
double mediaPares = [Link]()
.filter(n -> n % 2 == 0)
.mapToInt(Integer::intValue)
.average()
.orElse(0.0); // 6.0
9.4 Collectors
List<String> nomes = [Link]("Ana", "João", "Maria", "André");
// Agrupar por primeira letra
Map<Character, List<String>> grupos = [Link]()
.collect([Link](n -> [Link](0)));
// {A=[Ana, André], J=[João], M=[Maria]}
// Contar por grupo
Map<Character, Long> contagem = [Link]()
.collect([Link](n -> [Link](0), [Link]()));
// Juntar em String
String concatenado = [Link]()
.collect([Link](", ", "[", "]"));
// [Ana, João, Maria, André]
// Separar em dois grupos
Map<Boolean, List<String>> particao = [Link]()
.collect([Link](n -> [Link]() <= 3));
// {true=[Ana], false=[João, Maria, André]}
9.5 Optional
import [Link];
// Criar Optional
Optional<String> opt1 = [Link]("valor");
Página
Manual Completo de Programação em Java
Optional<String> opt2 = [Link]();
Optional<String> opt3 = [Link](null); // evita NPE
// Verificar e obter
if ([Link]()) {
[Link]([Link]());
}
// Forma funcional (preferida)
[Link]([Link]::println);
String resultado = [Link]("padrão");
String res2 = [Link](() -> "calculado");
String res3 = [Link](IllegalStateException::new);
// Encadeamento
Optional<Integer> tamanho = opt1
.map(String::toUpperCase)
.map(String::length); // Optional[5]
Página
Manual Completo de Programação em Java
10. Entrada e Saída (I/O)
10.1 Leitura e Escrita de Arquivos
import [Link].*;
import [Link].*;
// Escrever arquivo — forma simples (Java NIO)
Path caminho = [Link]("[Link]");
[Link](caminho, "Conteúdo do arquivo\n");
// Escrever múltiplas linhas
List<String> linhas = [Link]("Linha 1", "Linha 2", "Linha 3");
[Link](caminho, linhas);
// Ler arquivo completo
String conteudo = [Link](caminho);
List<String> todasLinhas = [Link](caminho);
// Ler linha a linha (eficiente para arquivos grandes)
try (Stream<String> stream = [Link](caminho)) {
[Link](l -> ![Link]())
.forEach([Link]::println);
}
10.2 BufferedReader e BufferedWriter
// Escrever com BufferedWriter
try (BufferedWriter writer = new BufferedWriter(new FileWriter("[Link]"))) {
[Link]("Primeira linha");
[Link]();
[Link]("Segunda linha");
}
// Ler com BufferedReader
try (BufferedReader reader = new BufferedReader(new FileReader("[Link]"))) {
String linha;
while ((linha = [Link]()) != null) {
[Link](linha);
}
}
10.3 Serialização de Objetos
import [Link].*;
// Classe serializável
public class Produto implements Serializable {
private static final long serialVersionUID = 1L;
Página
Manual Completo de Programação em Java
private String nome;
private double preco;
// transient — campo não serializado
private transient String senha;
}
// Serializar (salvar objeto em arquivo)
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("[Link]"))) {
[Link](new Produto("Notebook", 2500.0));
}
// Desserializar (carregar objeto do arquivo)
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("[Link]"))) {
Produto p = (Produto) [Link]();
}
Página
Manual Completo de Programação em Java
11. Concorrência e Threads
Java oferece suporte nativo a programação concorrente por meio de threads, permitindo
executar múltiplas tarefas em paralelo.
11.1 Criando Threads
// Forma 1: Estender Thread
public class MinhaThread extends Thread {
@Override
public void run() {
[Link]("Thread: " + getName() + " executando");
}
}
// Forma 2: Implementar Runnable (preferida)
Runnable tarefa = () -> {
[Link]("Tarefa executando em: " +
[Link]().getName());
};
// Iniciar threads
new MinhaThread().start();
new Thread(tarefa).start();
// Aguardar conclusão
Thread t = new Thread(tarefa);
[Link]();
[Link](); // bloqueia até t terminar
11.2 ExecutorService
import [Link].*;
// Pool de threads — mais eficiente que criar threads manualmente
ExecutorService executor = [Link](4);
// Submeter tarefas
for (int i = 0; i < 10; i++) {
final int num = i;
[Link](() -> {
[Link]("Processando " + num);
});
}
// Encerrar ordenadamente
[Link]();
[Link](30, [Link]);
// Future — obter resultado assíncrono
Página
Manual Completo de Programação em Java
Future<Integer> future = [Link](() -> {
[Link](1000);
return 42;
});
Integer resultado = [Link](); // bloqueia até obter resultado
11.3 Sincronização
public class Contador {
private int valor = 0;
// synchronized — apenas uma thread por vez
public synchronized void incrementar() {
valor++;
}
public synchronized int getValor() {
return valor;
}
}
// Usando AtomicInteger (mais eficiente para operações simples)
import [Link];
AtomicInteger contador = new AtomicInteger(0);
[Link](); // thread-safe sem synchronized
Página
Manual Completo de Programação em Java
12. Boas Práticas e Padrões
12.1 Convenções de Nomenclatura
Elemento Convenção Exemplo
Classes PascalCase ContaBancaria, PessoaFisica
Métodos camelCase (verbo) calcularSaldo(), getNome()
Variáveis camelCase saldoAtual, nomeCliente
Constantes UPPER_SNAKE_CASE MAX_TENTATIVAS, PI
Pacotes lowercase [Link]
Interfaces PascalCase (adj./cap.) Serializable, Comparable
Enums PascalCase DiaDaSemana, StatusPedido
12.2 Princípios SOLID
• S — Single Responsibility: cada classe tem uma única responsabilidade
• O — Open/Closed: aberta para extensão, fechada para modificação
• L — Liskov Substitution: subtipos devem substituir seus tipos base
• I — Interface Segregation: interfaces específicas são melhores que genéricas
• D — Dependency Inversion: dependa de abstrações, não de implementações
12.3 Dicas de Boas Práticas
3. Prefira imutabilidade — use final e objetos imutáveis quando possível
4. Valide parâmetros de entrada nos métodos públicos
5. Use try-with-resources para fechar recursos automaticamente
6. Prefira interfaces a implementações concretas nas declarações de variáveis
7. Evite NullPointerException — use Optional e verificações prévias
8. Escreva código limpo e auto-documentado com bons nomes
9. Use Streams e Lambdas para manipulação de coleções
10. Escreva testes unitários com JUnit 5
12.4 Exemplo: Record (Java 16+)
// Record — classe de dados imutável e concisa
public record Ponto(double x, double y) {
// Construtor compacto para validação
public Ponto {
if (x < 0 || y < 0) throw new IllegalArgumentException("Coordenadas
negativas");
Página
Manual Completo de Programação em Java
// Métodos adicionais são permitidos
public double distanciaOrigem() {
return [Link](x * x + y * y);
}
}
// Java gera automaticamente: construtor, getters, equals, hashCode, toString
Ponto p = new Ponto(3.0, 4.0);
[Link](p.x()); // 3.0
[Link]([Link]()); // 5.0
[Link](p); // Ponto[x=3.0, y=4.0]
12.5 Sealed Classes (Java 17+)
// Sealed class — controla quais classes podem estender
public sealed class Forma permits Circulo, Retangulo, Triangulo {}
public final class Circulo extends Forma {
public double raio;
public Circulo(double raio) { [Link] = raio; }
}
// Pattern matching com switch (Java 21)
double area = switch (forma) {
case Circulo c -> [Link] * [Link] * [Link];
case Retangulo r -> [Link] * [Link];
case Triangulo t -> [Link] * [Link] / 2;
};
Fim do Manual — Java SE 8 a 21
Bons estudos e boas programações! ☕
Página