Conceitos de Java

Conceitos essenciais de Java explicados a fundo, um de cada vez.

Ordenar

Collections

1

A Classe WeakHashMap

Como o WeakHashMap envolve cada chave em uma WeakReference para que as entradas sejam removidas automaticamente quando nada fora do mapa segura a chave com uma referência forte, e por que um valor que referencia a própria chave ou uma chave internada anula esse comportamento.

2
🔬 Lab

A Classe TreeMap

Como o TreeMap mantém as chaves em ordem ascendente através de uma árvore red-black, por que a igualdade de chaves ali é decidida por compareTo() em vez de equals()/hashCode(), e o custo O(log n) que isso paga.

3
🔬 Lab

A Classe HashMap

Como o armazenamento em tabela hash do HashMap oferece get/put O(1) em média, sem garantia de ordem de iteração, e como o put() substitui silenciosamente o valor de uma chave já existente.

4
🔬 Lab

A Classe LinkedHashMap

Como o LinkedHashMap adiciona iteração em ordem de inserção (ou de acesso) sobre a performance de busca do HashMap, e como sobrescrever removeEldestEntry() o transforma em um cache LRU limitado.

5
🔬 Lab

Comparators e Algoritmos de Coleção

Como Comparator desacopla completamente a ordenação de um tipo (diferente do único compareTo() fixo de Comparable), como comparing()/thenComparing() constroem comparators de múltiplas chaves sem um compare() escrito à mão, e o que os algoritmos estáticos de Collections (sort, shuffle, views unmodifiable/synchronized/checked) realmente garantem.

6
🔬 Lab

A Interface Collection

A interface raiz genérica do Collections Framework — o que add, remove e as operações em bloco garantem, e por que várias delas podem lançar exceção em runtime em vez de simplesmente não compilar.

7
🔬 Lab

A Interface Queue

Por que Queue define duas famílias paralelas de métodos — uma que lança exceção em caso de falha, outra que reporta a falha — e o que isso significa para filas vazias e de tamanho fixo.

8
🔬 Lab

A Classe PriorityQueue

Como o PriorityQueue ordena elementos por comparator em vez da ordem de inserção, via um heap, e por que iterar sobre ele não visita os elementos em ordem de prioridade da forma como poll() repetido faz.

9
🔬 Lab

A Interface Deque

Como Deque estende Queue para uma fila de duas pontas que também pode funcionar como pilha, e como suas famílias addFirst/addLast, peek e remove se dividem cada uma em uma versão que lança exceção e outra que reporta.

10
🔬 Lab

A Classe ArrayDeque

Como o armazenamento em array, sem restrição de capacidade, do ArrayDeque o torna a escolha recomendada pelo JDK para pilha/fila em vez do Stack legado ou LinkedList quando elementos nulos não são necessários.

11
🔬 Lab

A Interface Set

Como Set proíbe duplicatas, como SortedSet e NavigableSet acrescentam ordenação e buscas por correspondência mais próxima em cima dela, e por que suas range views são apoiadas no set original.

12
🔬 Lab

A Classe TreeSet

Como o TreeSet mantém os elementos em ordem crescente via uma estrutura de árvore, por que a unicidade ali é decidida por compareTo() em vez de equals(), e o custo O(log n) que isso paga.

13
🔬 Lab

A Classe HashSet

Como o armazenamento em tabela hash do HashSet oferece add/contains/remove O(1) em média, sem garantia de ordem de iteração, e o que quebra as buscas quando os campos relevantes para o hash de um elemento mudam.

14
🔬 Lab

A Classe LinkedHashSet

Como o LinkedHashSet adiciona iteração em ordem de inserção sobre a performance de busca do HashSet, passando uma lista ligada por dentro das entradas da tabela hash.

15
🔬 Lab

A Interface List

Como List constrói uma sequência posicional, que permite duplicatas, sobre Collection — acesso indexado, sublistas, ordenação e as listas não modificáveis produzidas por List.of().

16
🔬 Lab

Coleções Sequenciadas: SequencedCollection, SequencedSet, SequencedMap

As interfaces SequencedCollection/SequencedSet/SequencedMap da JEP 431 dão a toda coleção com uma ordem de encontro real — List, Deque, LinkedHashSet, TreeSet, LinkedHashMap, TreeMap — uma API uniforme de getFirst/getLast/addFirst/addLast/reversed(), excluindo deliberadamente HashSet, HashMap e PriorityQueue, já que nenhuma delas tem uma ordem de encontro estável para expor.

17
🔬 Lab

A Classe LinkedList

Como o armazenamento baseado em nós do LinkedList inverte o trade-off do ArrayList — acesso indexado O(n) em troca de inserção/remoção baratas — enquanto implementa List, Deque e Queue ao mesmo tempo.

18
🔬 Lab

A Classe ArrayList

Como o armazenamento em array redimensionável do ArrayList oferece acesso indexado O(1) ao custo de inserções/remoções O(n) fora do final, e como gerenciar sua capacidade diretamente.

19
🔬 Lab

Iterator vs Iterable

O que cada interface faz, por que Iterable te obriga a implementar Iterator, e por que as coleções do JDK são construídas dessa forma.

Concurrency

1

VarHandle: Acesso Lock-Free a Campos Comuns

O VarHandle (JEP 193) permite que um programa aplique acesso com força atômica e volatile a um campo comum ou elemento de array, na força de ordenação de memória escolhida, sem envolvê-lo em uma classe como AtomicInteger.

2

ThreadLocal: Estado por Thread, Vazamentos e InheritableThreadLocal

ThreadLocal dá a cada thread sua própria cópia isolada de uma variável através de um mapa por thread, o que é poderoso mas vaza em threads de pool a menos que seja combinado com remove, e InheritableThreadLocal copia esse valor para threads filhas apenas no momento da criação.

3

O Modelo de Memória do Java: Happens-Before e Reordenação

As regras formais de happens-before do Capítulo 17 da JLS que determinam quando uma escrita em uma thread tem visibilidade garantida para uma leitura em outra.

4

Memória de Stack de Thread: Locais, Frames e Por Que Não É Compartilhada

Por que a stack de cada thread — suas variáveis locais, parâmetros e frames de chamada — é privada daquela thread e nunca é fonte de condições de corrida, enquanto referências armazenadas na stack ainda podem apontar para estado compartilhado e sujeito a corrida na heap.

5
🔬 Lab

CompletableFuture: Compondo Trabalho Assíncrono

Como thenApply, thenCompose, thenCombine, allOf e os handlers de exceção compõem trabalho assíncrono sem bloquear — e as armadilhas de futures aninhados, common pool e exceções engolidas que vêm junto.

6
🔬 Lab

Scoped Values: Um Substituto Moderno para o ThreadLocal

ScopedValue (finalizado no Java 25 pela JEP 506) substitui o slot mutável e propenso a leak por thread do ThreadLocal por um binding imutável cujo tempo de vida é exatamente a extensão dinâmica de uma lambda run()/call() — sem set(), sem remove() para esquecer, e herança automática por subtasks disparadas em um StructuredTaskScope.

7
🔬 Lab

Concorrência Estruturada: StructuredTaskScope

StructuredTaskScope (ainda preview no Java 25, JEP 505) transforma um fan-out de subtarefas concorrentes em um bloco try-with-resources que é dono do tempo de vida delas — nenhuma tarefa pode sobreviver ao seu escopo, as tarefas irmãs são canceladas automaticamente em caso de falha, e a operação inteira aparece aninhada em um thread dump em vez de como um pool plano de Futures.

8
🔬 Lab

Configurando e Dimensionando Thread Pools

Cobre a fórmula do JCIP para calcular um tamanho ótimo de thread pool e a API do ThreadPoolExecutor para filas de trabalho, políticas de saturação, thread factories e hooks de extensão.

9

Reduzindo Contenção de Locks: Escopo, Granularidade e Striping

Técnicas concretas para diminuir o impacto de um lock contencioso — reduzir seu escopo, dividi-lo ou fazer striping, evitar campos quentes, e quando trocá-lo por um read-write lock ou um atomic.

10

Encerrando um ExecutorService, e Como a JVM Decide Sair

Compara o shutdown() gracioso com o shutdownNow() agressivo, o idioma awaitTermination()/close(), poison pills para consumidores baseados em fila, handlers de exceção não capturada, e shutdown hooks da JVM e daemon threads.

11
🔬 Lab

Task Cancellation: Interrupção Feita Corretamente

Como Thread.interrupt() funciona de fato como uma flag de status cooperativa, por que engolir InterruptedException é o bug de concorrência mais comum, e como cancelar tasks corretamente via política de interrupção e Future.cancel().

12
🔬 Lab

BlockingQueue e o Padrão Produtor-Consumidor

Como o put/take bloqueante de BlockingQueue reduz o padrão produtor-consumidor a poucas linhas de código, e por que filas limitadas (bounded) oferecem backpressure real em vez de apenas adiar um OutOfMemoryError.

13
🔬 Lab

Coleções Concorrentes: Por Que Thread-Safe Não Basta, e o Que o ConcurrentHashMap Faz Diferente

Por que uma ação composta construída a partir de chamadas thread-safe numa coleção sincronizada ainda pode ter race condition, e como ConcurrentHashMap e CopyOnWriteArrayList resolvem isso com iteração fracamente consistente e métodos de ação composta atômicos em vez disso.

14
🔬 Lab

Deadlock: Ordem de Locks, Open Calls e Como Evitá-lo

Como deadlocks de ordem de lock acontecem entre threads, e como uma ordem consistente de locks, open calls e tentativas de lock com timeout previnem e diagnosticam esse problema.

15

AbstractQueuedSynchronizer — o que existe por baixo de Lock e Semaphore

A maquinaria interna compartilhada — um campo de estado, uma fila de threads e alguns hooks sobrescrevíveis — sobre a qual ReentrantLock, Semaphore e CountDownLatch são construídos.

16

Visibilidade e Publicação Segura Entre Threads

Explica por que leituras não sincronizadas entre threads podem ver valores obsoletos ou corrompidos, o que volatile de fato garante, e como publicar um objeto para outra thread com segurança.

17
🔬 Lab

O Fork/Join Framework

Um motor de divisão-e-conquista para paralelismo real em múltiplos núcleos, onde um ForkJoinPool executa RecursiveAction/RecursiveTask divididos recursivamente via work-stealing.

18
🔬 Lab

As Ferramentas de Concorrência: Executors, Sincronizadores e Locks

O kit java.util.concurrent — executors e thread pools, Callable/Future, primitivas de coordenação como CountDownLatch e Semaphore, Locks explícitos e variáveis atômicas — como alternativa de mais alto nível ao código artesanal com Thread e synchronized.

19
🔬 Lab

Modelo de Threads: Controle Legado vs. Virtual Threads

Por que Thread.suspend/resume/stop foram descontinuados por corromperem estado compartilhado, o padrão de desligamento cooperativo que os substituiu, e por que virtual threads resolvem um problema diferente (custo de thread) em vez desse mesmo problema de corretude.

Language Features

1

Pontos de Código Unicode e Pares Substitutos em String

String armazena texto como unidades de código UTF-16 de 16 bits, então caracteres fora do Plano Multilíngue Básico, como a maioria dos emojis, precisam de um par substituto (surrogate pair) de dois caracteres para representar um único ponto de código Unicode.

2

Collectors de Stream e Streams Paralelas

Um mergulho profundo nos Collectors de múltiplos níveis (groupingBy, partitioningBy, toMap, teeing, Collector.of customizado) e na mecânica e nas armadilhas das streams paralelas.

3

O String Pool e o Interning

Literais de string são automaticamente internados em um pool compartilhado, então == é true entre dois literais com o mesmo conteúdo mas false contra um new String(...) com conteúdo idêntico — uma consequência direta e previsível de onde cada string veio, não uma peculiaridade da linguagem.

4

Métodos Default, Static e Private em Interfaces

Como métodos default, static e private permitem que uma interface carregue comportamento para que uma API publicada possa crescer sem quebrar quem a implementa, e as regras exatas que o Java usa quando dois defaults herdados colidem.

5

Corpos de Construtor Flexíveis

Desde o JDK 25, um construtor pode executar statements antes de super(...) ou this(...), dividindo seu corpo em um prólogo que valida argumentos e inicializa seus próprios campos e um epílogo que finalmente pode usar o objeto em construção.

6

Classes Aninhadas e Internas

Os quatro tipos de classe-dentro-de-classe — nested static, inner, local e anônima — diferem pela quantidade de contexto do enclosing que cada uma captura, e saber qual delas você escreveu revela o que ela alcança, o que mantém vivo em memória, e se uma lambda ou um record diriam a mesma coisa melhor.

7
🔬 Lab

Switch Expressions: yield, Rótulos com Arrow e Exaustividade

O switch statement e a switch expression são duas construções que compartilham uma palavra-chave — a forma com dois-pontos cai através dos casos (fall-through) e não produz nada, enquanto uma expression em forma arrow executa exatamente um ramo, produz um valor via yield quando o ramo é um bloco, e precisa ser comprovadamente exaustiva ou o compilador a rejeita.

8
🔬 Lab

Text Blocks: Literais String Multi-Linha

Como o text block com aspas triplas escreve SQL, JSON e HTML multi-linha sem escapes de \n ou concatenação com + — e o algoritmo preciso de whitespace incidental por trás disso, onde a própria coluna do delimitador de fechamento decide quanta indentação é removida, espaços finais desaparecem a menos que sejam presos com \s, e terminadores de linha são normalizados para \n. Continua sendo exatamente uma String em runtime, sem interpolação e sem forma de diferenciá-la de um literal comum.

9

var: Inferência de Tipo de Variável Local

var permite que o compilador infira o tipo estático de uma variável local a partir do seu inicializador — não é tipagem dinâmica nem Object, e combiná-lo com o operador diamond silenciosamente produz ArrayList<Object>.

10

Sobrecarga de Métodos: Resolução em Tempo de Compilação e Suas Armadilhas

A resolução de sobrecarga acontece em tempo de compilação, com base no tipo declarado dos argumentos, e não no tipo em runtime — diferente do que ocorre com overriding — e essa diferença molda como as assinaturas de métodos deveriam ser projetadas.

11

Varargs: Custo de Performance e Heap Pollution com Generics

Varargs alocam implicitamente um array em toda chamada e, combinados com generics, podem deixar um ClassCastException escapar do compilador — o motivo, e o que @SafeVarargs de fato promete.

12

Padrões de Enum: Corpos com Strategy, EnumSet e EnumMap

Use corpos de método específicos por constante para comportamento individual por constante, e EnumSet/EnumMap em vez de campos de bits e arrays indexados por ordinal.

13
🔬 Lab

Fundamentos da Stream API

Por que uma stream é um conduto preguiçoso e de uso único em vez de uma estrutura de dados, como o formato do pipeline (fonte → operações intermediárias → operação terminal) faz com que filter-then-findFirst pare antecipadamente em vez de varrer tudo, como Collectors e as especializações de stream primitivas funcionam por baixo dos panos, e quando streams paralelas realmente ajudam.

14
🔬 Lab

Expressões Lambda

Como uma expressão lambda implementa o único método abstrato de uma interface funcional, as formas de sintaxe com corpo de expressão vs. corpo de bloco, o catálogo java.util.function, a regra effectively-final por trás da captura de variáveis, e os quatro tipos de referência a método.

15

Project Valhalla: Value Classes

Por que objetos custam mais que primitivos (identidade, header, alocação no heap, pressão sobre o GC), como Value Classes permitem que a JVM elimine esse overhead para tipos que são apenas seus dados, e por que List<int> ainda não existe por causa do type erasure dos generics.

16
🔬 Lab

Records e Tipos Sealed

Como um record reduz uma classe carregadora de dados a uma linha (construtores canônico/compacto, equals/hashCode/toString de graça, imutabilidade rasa), e como classes/interfaces sealed substituem o "qualquer um pode estender isso" por uma lista permits explícita e exaustiva — a combinação que torna seguro modelar hierarquias fechadas.

17
🔬 Lab

Generics: Tipos Limitados, Wildcards e Erasure

Como tipos parametrizados movem casts e verificações de incompatibilidade de tipo do runtime para o tempo de compilação, o que tipos limitados e wildcards PECS (extends/super) realmente restringem, e por que erasure significa que só existe, de fato, um arquivo de classe por tipo genérico em tempo de execução.

18
🔬 Lab

Pattern Matching

Como instanceof, switch e record patterns permitem testar a estrutura de um objeto e extrair seus dados em um único passo, em vez de fazer cast depois de checar o tipo.

API Design & Craft

1

equals() vs compareTo()

Por que equals() retorna boolean e compareTo() retorna int, de onde cada um vem (Object vs Comparable), o que significa uma ordenação "consistente com equals", e por que new BigDecimal("1.0") não é igual a new BigDecimal("1.00").

2

Object.clone() e o Anti-Padrão Cloneable

Object.clone() e a interface marcadora Cloneable realizam uma cópia rasa que ignora o construtor, com armadilhas estruturais envolvendo herança e campos final, que copy constructors e static factories evitam.

3

Programação Orientada a Dados

Data-Oriented Programming separa deliberadamente dados imutáveis e transparentes (records dentro de uma hierarquia sealed) da lógica que atua sobre eles, de modo que um switch exaustivo com record patterns permite ao compilador garantir que toda variante seja tratada.

4
🔬 Lab

Optional: Uso Correto e os Próprios Avisos da API

Optional existe para tornar 'isso pode não ter um valor' parte do tipo de retorno de um método em vez de um null que quem chama precisa lembrar de checar — e por que o próprio JDK desaconselha usá-lo como campo, parâmetro ou dentro de uma coleção, além do anti-padrão isPresent()-então-get() e a armadilha de eagerness orElse-vs-orElseGet que pegam a maioria dos primeiros usos.

5
🔬 Lab

Serialization: Por Que É Perigosa e Como Conter o Risco

Implementar Serializable ignora as checagens de invariantes do construtor da sua classe e expõe seus internos como API permanente — veja por que, e como disciplina no readObject, o padrão serialization proxy e o ObjectInputFilter contêm esse risco.

6

Design de Exceções: Quando Lançar, e Checked vs. Unchecked Como Escolha

Como decidir se uma falha deveria sequer ser modelada como exceção, e se um novo tipo de exceção deveria ser checked ou unchecked.

7

Validação de Parâmetros e Fail-Fast

Valide os parâmetros de um método ou construtor logo no topo do corpo e lance imediatamente uma exceção clara, em vez de deixar um argumento inválido se propagar até falhas confusas ou um estado de objeto corrompido.

8

Composição em vez de Herança, e Interfaces vs. Classes Abstratas

Estender uma classe que você não controla é frágil porque depende de padrões internos de "auto-uso" não documentados, e composição com forwarding evita esse risco — a mesma limitação de herança única também explica por que interfaces, e não classes abstratas, costumam ser a forma certa de definir um tipo público.

9

Classes Imutáveis e Cópia Defensiva

Tornar uma classe verdadeiramente imutável exige mais do que campos final — significa copiar argumentos mutáveis na entrada e campos mutáveis na saída, para que nenhuma outra referência ao estado do objeto jamais escape.

10
🔬 Lab

Os Contratos de equals(), hashCode() e toString()

Os contratos documentados por trás dos três métodos mais sobrescritos de Object, por que quebrar a simetria ou pular hashCode() falha silenciosamente em vez de na compilação, e como records satisfazem os três de graça.

11

Singletons e Classes Utilitárias Não Instanciáveis

Compare as três formas de escrever um singleton em Java — campo público, static factory, enum de um único elemento — e o idioma do construtor privado para classes utilitárias não instanciáveis.

12
🔬 Lab

Métodos de Fábrica Estáticos e o Padrão Builder

Métodos estáticos nomeados podem substituir ou complementar construtores para criar objetos de forma mais clara, cacheável e flexível quanto a subtipos, e o padrão Builder domina classes com muitos campos opcionais.

13

Fundamentos de Exception Handling

O mecanismo estruturado do Java para erros em tempo de execução — try/catch/finally, throw/throws, exceções checked vs. unchecked, subclasses de exceção customizadas, e exceções encadeadas.

Core APIs & Tooling

1

Project Leyden: AOT Cache, Warm-up e Startup

Como o AOT cache do Project Leyden guarda classes, perfis de métodos, objetos e (em breve) código compilado de uma execução de treino para encurtar startup e warm-up sem abandonar a JVM dinâmica, e o que cada JEP entrega de fato hoje.

2

Arrays: Ordenação, Busca e Comparação Profunda

Cobre a divisão de Arrays.sort entre primitivos e Comparator, o comportamento indefinido e silencioso de binarySearch em dados não ordenados, e por que equals/toString precisam de suas variantes "deep" para arrays aninhados.

3

Weak, Soft e Phantom References: Tipos de Referência Cientes do GC

Explica a hierarquia de referências strong/soft/weak/phantom, o polling via ReferenceQueue, e como o Cleaner substitui o Object.finalize() para limpeza determinística de recursos nativos.

4

Criptografia em Java: MessageDigest, Cipher e KeyStore

Cobre a arquitetura de providers JCA/JCE e o uso correto de MessageDigest, SecureRandom, Cipher, Signature e KeyStore, incluindo por que hashing simples e Random são substitutos inseguros para hashing de senhas e geração de tokens seguros.

5

Classloading: O Modelo de Delegação e Class Loaders Customizados

Como a JVM carrega, faz o linking e inicializa classes através de uma hierarquia de delegação parent-first, e o que acontece quando você escreve um class loader customizado ou carrega a mesma classe duas vezes.

6

Formatter e Especificadores de Formato

String.format/printf/Formatter compartilham o mesmo motor de conversão — width e precision significam coisas diferentes dependendo da conversão, as flags de vírgula/+/espaço/( cobrem a maioria das necessidades reais de formatação, e a indexação de argumentos n$/< permite reutilizar um argumento em vários especificadores sem repeti-lo.

7

A Classe Scanner

Scanner tokeniza a entrada vinda de System.in, de uma String ou de um arquivo via pares hasNextX()/nextX(), com uma armadilha clássica: nextInt() deixa a quebra de linha final sem consumir, então um nextLine() seguinte lê uma string vazia em vez da próxima linha de verdade.

8

Introspecção do Ambiente de Execução: System Properties, Variáveis de Ambiente e Runtime

System.getenv() (ambiente do SO, herdado por processos filhos), System.getProperty() (escopo da JVM, definido via -D) e Runtime (fatos ao vivo como availableProcessors() e Runtime.version()) são três canais distintos para perguntar a uma JVM em que ela está rodando e como foi configurada.

9

Logging em Java: SLF4J, Logback e java.util.logging

A API nativa de logging do JDK, java.util.logging, raramente é chamada diretamente; código real faz logging através da fachada SLF4J contra um backend trocável (geralmente Logback), usando placeholders {} e MDC para saída estruturada e correlacionável.

10

jlink e jdeps: Imagens de Runtime Customizadas

O jlink liga módulos do JDK e da aplicação em uma imagem de runtime autocontida contendo só o que é alcançável, com o jdeps descobrindo primeiro a lista real de módulos — distribuindo um runtime Java enxuto em vez de um JDK completo.

11

Compilação Nativa com GraalVM Native Image

O GraalVM reúne um JIT (o compilador Graal) mais o native-image, um compilador ahead-of-time que transforma uma aplicação Java em um executável nativo autocontido — trocando uma premissa de mundo fechado sobre reflection, proxies e recursos por startup quase instantâneo e uma pegada muito menor.

12

Method Handles e Geração de Classes em Runtime

Além da reflection de inspecionar-e-invocar: method handles com verificações de acesso em tempo de lookup, setAccessible contra o InaccessibleObjectException do sistema de módulos e --add-opens, e três formas de fabricar uma classe em runtime — um ClassLoader customizado, o JavaCompiler em memória e a API padrão Class-File do java.lang.classfile.

13

Vector API: Aritmética SIMD Explícita

Usar a API incubadora jdk.incubator.vector para expressar aritmética de arrays como operações SIMD explícitas por lane, em vez de depender do JIT para auto-vetorizar um laço escalar.

14
🔬 Lab

Aritmética Exata com BigDecimal e BigInteger

Como java.math.BigDecimal e BigInteger oferecem precisão arbitrária e arredondamento explícito onde double e long silenciosamente perdem dinheiro ou estouram.

15

Resource Bundles e Locale

Como Locale identifica um idioma e uma região, como ResourceBundle expande uma requisição em uma cadeia de arquivos .properties candidatos, e por que o locale padrão da JVM é tentado antes do bundle base, neutro em relação a idioma.

16

Foreign Function and Memory API

A API java.lang.foreign, padrão desde o JDK 22, permite que Java puro chame funções de bibliotecas nativas e gerencie memória off-heap com ciclos de vida vinculados a arenas, substituindo o código C escrito à mão do JNI.

17
🔬 Lab

Processamento de JSON em Java

O JDK ainda não tem suporte a JSON, então trabalhar com JSON significa escolher uma biblioteca e um de três modelos de processamento — data binding, o tree model, ou streaming — todos oferecidos pelo Jackson como o padrão de fato.

18

O Java Platform Module System (JPMS)

O que module-info.java realmente declara — requires, requires transitive, exports, opens, uses/provides — e por que um pacote não exportado é invisível para outros módulos mesmo quando todo tipo dentro dele é público. Cobre o módulo sem nome (onde a maior parte do código de aplicação ainda roda, sem nenhuma dessas garantias), módulos automáticos como ponte de migração, jlink para imagens de runtime mínimas, e os trade-offs honestos: pacotes divididos proibidos, a tensão entre opens e encapsulamento forte, e o quão lenta tem sido a adoção no mundo real.

19
🔬 Lab

java.time: Datas, Horários e Durações

java.time substituiu o java.util.Date e o Calendar — mutáveis, thread-unsafe e com mês indexado em 0 — por uma família de tipos pequenos e imutáveis, cada um modelando exatamente uma ideia: por que um Instant não tem getYear(), por que Duration e Period genuinamente não podem ser o mesmo tipo, o que \"mais um dia\" significa numa transição de horário de verão, e por que um DateTimeFormatter static final é seguro onde um SimpleDateFormat compartilhado era um bug de produção.

20

Convenções de Nomenclatura em Java

As regras tipográficas do Java (capitalização de pacotes, classes, métodos, campos e parâmetros de tipo) e as regras gramaticais (frases nominais para classes, frases verbais para métodos de ação, is/has para booleanos) que mantêm o código legível e previsível.

21

Escrevendo Doc Comments para Elementos de API Exportados

Como escrever doc comments (comentários de documentação) eficazes do Javadoc — contratos, tags, descrições resumo e herança — para toda classe, método e campo exportados.

22
🔬 Lab

Varredura do Classpath via Reflection

Como um component scan funciona de fato por baixo dos panos: uma varredura recursiva de diretórios sobre arquivos .class compilados, Class.forName + isAnnotationPresent para achar classes marcadas por anotação, e por que frameworks de verdade leem metadados de bytecode via ASM em vez de carregar toda classe candidata.

23
🔬 Lab

JShell: o REPL do Java

Como o JShell permite avaliar expressões, declarar variáveis/métodos/classes, e obter feedback imediato sem um wrapper completo de classe/método main — a convenção de variável de resultado, referências antecipadas, os /commands essenciais, e como ele difere do lançamento de código-fonte em arquivo único.

24
🔬 Lab

Essenciais do java.lang: Comparable, AutoCloseable, StackWalker, ProcessBuilder

O contrato de ordenação natural de Comparable<T> e sua recomendação de consistência com equals, as regras de idempotência de AutoCloseable vs. Closeable, o StackWalker como o substituto moderno e preguiçoso para inspeção de stack trace, e ProcessBuilder/Process/ProcessHandle para lançar e gerenciar processos do sistema operacional.

25
🔬 Lab

Annotations: Retention, Meta-Annotations e Reflection

Como @Retention/RetentionPolicy controlam se uma annotation sobrevive além do código-fonte, as meta-annotations @Target/@Inherited/@Repeatable, a leitura de annotations em tempo de execução via AnnotatedElement, e as annotations embutidas @Deprecated/@SafeVarargs/@FunctionalInterface/@Documented.

26
🔬 Lab

Expressões Regulares com Pattern e Matcher

Por que Pattern.compile() e Matcher existem como dois objetos separados (compile uma vez, faça match muitas vezes), a diferença entre find()/matches()/lookingAt(), e como grupos de captura — numerados e nomeados — extraem substrings de um match em vez de apenas testar sim/não.

I/O & Networking

1

NIO Channels e Buffers: O Modelo de I/O Não Bloqueante

Explica o modelo de Channel orientado a buffer em java.nio.channels, cobrindo o estado do ByteBuffer, buffers diretos vs. heap, zero-copy e I/O mapeado em memória do FileChannel, sockets não bloqueantes, e leituras/escritas scatter/gather.

2

URI, URL e URN

URI é sintaxe pura, URL sabe também localizar e abrir um recurso, e URN nomeia um recurso sem dizer onde encontrá-lo — e desde o JDK 20 o JDK direciona a construção via URI.toURL() em vez dos construtores de URL, agora deprecados.

3

Servidores Multi-Cliente e Unix Domain Sockets

Separar o loop de accept de um ServerSocket da conversa por cliente para que o servidor realmente atenda clientes de forma concorrente, e usar Unix domain sockets (JEP 380, JDK 16) como uma alternativa mais rápida, protegida por permissões de arquivo e estritamente local ao TCP loopback.

4

O Servidor HTTP Embutido do JDK

O JDK distribui um servidor HTTP oficialmente suportado no módulo jdk.httpserver — HttpServer, HttpExchange, HttpsServer com um SSLContext para TLS, e SimpleFileServer/jwebserver — dando um endpoint HTTP sem dependências que a própria documentação escopa explicitamente para testes, desenvolvimento e depuração, não produção.

5
🔬 Lab

Sessões HTTP por Baixo dos Panos

Como o estado de sessão é simulado sobre um HTTP sem estado — um ID de sessão aleatório, um round trip Set-Cookie/Cookie e um map do lado servidor indexado por esse ID — além do que falta na versão mínima (expiração, invalidação, armazenamento externalizado) e os atributos de segurança de cookie atuais (Secure, SameSite).

6
🔬 Lab

Sockets e a Anatomia Bruta de uma Requisição HTTP

Como ServerSocket/Socket implementam a primitiva accept-connect-read-write por trás de todo web server, e o formato literal, em nível de byte, de uma requisição/resposta HTTP/1.1 (request line, headers, terminador de linha em branco, corpos com Content-Length/chunked, classes de status code).

7
🔬 Lab

java.io: Streams, Fechamento de Recursos e Serialização

A separação entre stream de bytes e stream de caracteres (InputStream/OutputStream vs. Reader/Writer), como Closeable/AutoCloseable/Flushable e try-with-resources garantem a limpeza de recursos com exceções suprimidas, buffering e PrintWriter, e como Serializable/ObjectInputFilter transformam um grafo de objetos em bytes protegendo contra ataques de deserialização.

8
🔬 Lab

NIO.2: A API Path e Files

Como o java.nio.file substitui o java.io.File por exceções informativas e específicas em vez de retornos booleanos, adiciona o DirectoryStream para iteração de diretório fechável/filtrável, suporte de primeira classe a links simbólicos e o WatchService para reagir a mudanças no sistema de arquivos em vez de fazer polling.

9
🔬 Lab

HttpClient: A API Moderna do java.net.http

Como o padrão builder do HttpClient substituiu a API de baixo nível e pouco prática do HttpURLConnection — send() síncrono vs. sendAsync() assíncrono retornando um CompletableFuture — e como o BodyHandlers decide em que formato o corpo da resposta chega.