O Java 25 roda um único arquivo-fonte com um comando e um void main simples, sem nenhuma classe para escrever antes. Veja o que o JDK contém, por que o Java 25 é a versão para aprender e como ler erros de compilação e exceções.
Toda variável em Java guarda um valor primitivo ou uma referência a um objeto. Saber qual dos dois explica o overflow silencioso, a passagem por valor, == versus equals e por que dois Integer com 128 não são iguais.
O if e os laços de Java parecem os de C, com algumas regras que pegam bugs reais. O switch antigo cai para o próximo case por padrão, e as switch expressions corrigem isso e fazem o compilador conferir cada valor do enum.
Uma classe Java descreve o que um objeto guarda e o que ele sabe fazer, e um construtor decide como cada objeto começa a vida. Aprenda campos, this, construtores, private, static e final rodando programas pequenos.
Strings em Java nunca mudam, então toda edição cria uma nova. Aprenda os métodos de String e suas armadilhas, por que += num laço copia tudo, StringBuilder, text blocks, Unicode e arrays com os helpers de Arrays.
Um record Java declara uma pequena classe de dados imutável numa linha, e o compilador escreve o construtor, os accessors, equals, hashCode e toString. Veja o que os records dão, o que recusam e onde ficam devendo.
Interfaces dizem o que um tipo sabe fazer, a herança dá a uma classe tudo o que a classe pai faz, e a composição embrulha um objeto. Aprenda métodos default, super, classes abstratas e a armadilha da classe base frágil rodando programas pequenos.
Sealed types dão ao Java uma lista fechada de subtipos, e o pattern matching deixa um switch testar e desmontar cada um. Juntos, eles transformam um caso esquecido num erro de compilação em vez de um bug silencioso.
O Java divide as exceções em checadas, que o compilador obriga você a tratar, e não checadas, que ele deixa passar. Aprenda try, catch e finally, como lançar e encapsular exceções direito e como o try-with-resources fecha tudo na ordem inversa.
Um HashMap do Java encontra chaves com hashCode e equals, então um contrato quebrado ou uma chave alterada depois do put faz entradas sumirem. Veja as regras, por que o TreeSet usa compareTo e qual coleção escolher.
Generics deixam o compilador verificar o que entra numa lista, numa caixa ou num método, e depois apagam essa informação antes de o programa rodar. Aprenda limites, wildcards, PECS e como ler uma assinatura do JDK rodando programas pequenos.
Lambdas em Java transformam um pequeno comportamento num valor, e streams encadeiam esses valores em pipelines preguiçosos. Veja como um pipeline roda de verdade, quais collectors usar e quando um laço simples fica mais claro.
O Java deixa qualquer referência ser null, então um valor ausente pode derrubar o código longe de onde sumiu. Objects e Optional deixam a ausência visível, e java.time faz você dizer de qual momento, em qual cidade, está falando.
Monte um projeto Java de dois módulos só com javac, jar e java. Veja como pacotes, imports, o classpath, arquivos JAR e o module-info.java se encaixam, e o que o Maven e o Gradle acrescentam por cima.
Onde o Java guarda suas variáveis e objetos, como o garbage collector decide o que liberar, por que um programa com garbage collection ainda pode vazar ou ficar sem memória, e como o JIT deixa o código mais rápido quanto mais ele roda.
Duas threads Java que atualizam a mesma variável podem perder escritas em silêncio. Veja por que count++ é uma condição de corrida, como synchronized, volatile, atomics e locks resolvem isso, e como forçar e detectar um deadlock.
Os executors do Java rodam suas tarefas num pool fixo de threads e devolvem um Future. Aprenda submit, invokeAll, cancelamento, cadeias de CompletableFuture, timeouts, semáforos e blocking queues, com saída que nunca varia.
O Java consegue rodar cem mil tarefas bloqueantes em poucas threads do sistema operacional. Veja como virtual threads montam e desmontam, o que ainda as prende, por que ScopedValue substitui ThreadLocal e como StructuredTaskScope cancela o trabalho que falha.
O JDK do Java chama e serve HTTP sem bibliotecas. Aprenda o HttpClient, síncrono e assíncrono, e depois construa um pequeno serviço de tarefas em JSON sobre o HttpServer embutido, com virtual threads, status codes certos e um encerramento limpo.
Monte um pequeno test runner só com o JDK, a partir de uma anotação e de reflexão, teste código package-private com –patch-module e distribua um serviço Java como JAR modular, imagem de runtime do jlink e instalador do jpackage.