Java 101

Como começar a aprender Java

Como começar a aprender Java


A intenção desse material é te apresentar o básico sobre Java oferecendo ferramentas para que você possa aprender a programar. Nenhum material por sí só fará o trabalho completo, para que você possa se tornar um desenvolvedor é preciso muito exercício, por isso vá lentamente avançando sobre os tópicos propostos e fazendo todos os exercícios propostos.

Nesse sessão você vai aprender:

  • O que é Java

  • Como criar seu primeiro programa Java


Nos últimos meses muitas pessoas vem me perguntando por onde começar a desenvolver Java. Eu sei que existem vários cursos na internet que tem essa resposta e não quero me propor a criar um curso Java. Creio que o conhecimento deve ser livre e sem escassez. Por isso vou te apresentar o básico que você deve saber sobre Java.

Eu vou tentar seguir a ordem dessa thread que fiz em dezembro.

java thread
Figura 1. Thread que fiz no Twitter em dezembro de 2021

Java é um ecossistema

Muitos tendem a querer comparar Java com outras linguagens. Alguns tem a pretensão de comparar Java com linguagens como Javascript ou mesmo Scala. Esse é um erro crasso! Essa comparação não tem sentido porque o Java não é apenas uma linguagem, mas um ecossistema.

Primeiro para entender melhor vamos tentar compreender melhor o que é uma linguagem de programação…​

Quando a computação eletrônica começou a se popularizar, existiam inúmeras plataformas e cada uma delas haviam um conjunto de instruções. Para desenvolver qualquer software era preciso conhecer o hardware e o conjunto de instruções que existem naquele hardware. Quer ver um exemplo? Tenta navegar no código da Apollo 11 para tentar entender algo. É praticamente impossível, até mesmo para quem já desenvolveu em Assembly. Isso acontece porque o conjunto de instruções e a arquitetura do hardware são completamente diferentes das máquinas que temos hoje.

Assembly
Assembly ou linguagem de montagem é uma notação legível por humanos para o código de máquina que uma arquitetura de computador específica usa, utilizada para programar códigos entendidos por dispositivos computacionais.
apollo11
Figura 2. Olha o código da ignição da Apolo 11! 😲

Com o tempo as máquinas ganharam um padrão, tanto de processadores como de Opcodes. Hoje sabemos que existe um processador, um barramento, memória, registradores, etc…​ Esses componentes variam um pouco de arquitetura pra arquitetura, mas eles continuam seguindo um padrão. Abaixo você pode ver a documentação de um opcode.

opcode
Figura 3. Exemplo de Opcode

— Cara qual a relação disso com Java?

Bom, vamos lá! Eu vou chegar lá! Eu prometo! Tudo que um computador reconhece são opcodes! Nenhum computador entende nenhuma linguagem de programação. Ah, mas você vai me dizer que algumas pessoas desenvolvem assembly…​ Sim! Mas mesmo para quem faz esses programas é preciso transcrever o programa em linguagem de máquina. Por exemplo, no opcode acima, o computador não sabe o que é NOP, ele só sabe que a operação 01 não deve produzir nenhum efeito. Então todo programa precisa ser compilado para uma série de instruções que chegam a praticamente o formato de máquina. Estou falando do famoso EXE do Windows. E esses programas também dependem de uma série de bibliotecas do sistema operacional para o qual foram compilados.

Até 1990 era comum um programa ser compilado para uma máquina especifica. Quem já trabalhou com Linux nos anos 2000 sabe o que é isso, você tinha que baixar o código fonte de um programa e compilar ele para a sua distribuição pois na maioria dos casos as versões de dependência eram muito especificas. Por isso uma grande empresa do Vale do Silício teve uma grande ideia! E se escrevêssemos uma linguagem em que ao se escrever um código ele poderá ser executado em qualquer lugar?

O ano era 1991 e a Sun já começava a se preparar para embarcar software em dispositivos portáveis e eletrodomésticos. Para isso era preciso de uma linguagem em que se pudesse criar programas sem nenhuma dependência com a arquitetura do processador e nem com o sistema operacional. Mas existia um grande desafio: como fazer para encapsular toda a lógica do hardware e do sistema operacional? Por isso surgiu algo que é tão importante quanto a linguagem Java: a Java Virtual Machine! Ou JVM para os mais íntimos…​

A JVM é um programa que lê um conjunto de classes e executa como se fosse um processador em alto nível. Ela tem uma arquitetura similar a uma máquina e instruções, como se fosse um processador. Se você for curioso, pode ler a especificação dela, pois é aberta e pode ser acessada por qualquer fornecedor que queira porta ela em seu sistema operacional.

— Ah, mas Java nem é tão popular!

Então agora para e olha para o transformador que existe na sua rua…​ E se eu te dissesse que é provável que existe uma JVM rodando perto dele para monitorar esse transformador específico? Você acreditaria? Em algumas cidades isso existe. E só é possível porque a JVM é portátil em qualquer tipo de dispositivo.

Como eles tinha requisitos de portabilidade para criar o Java, foi preciso criar uma máquina virtual poderosa e é ela quem tem grande parte do crédito da popularidade da linguagem. Ao abstrair as particularidades de vários sistemas operacionais e hardwares, foi possível se economizar tempo escrevendo e compilando código.

— Então você tá falando que o Java é famoso só por causa da JVM?

Óbvio que não! A JVM já vem com uma biblioteca padrão que é muito poderosa. Podemos ter acesso a biblioteca de coleções que é poderosa, a biblioteca de Reflections foi a base da grande maioria dos frameworks dos anos 2000, etc…​ A JVM era poderosa e ela era parte do que chamamos Java. Ela era tão boa que surgiram linguagens que compilavam para rodar JVM e algumas delas são bem populares como: Kotlin, Groovy, Scala e Clojure.

— Ah, mas Java é chato. Não dá nem pra escrever um programa sem ter um objeto! Porque tem que sempre escrever um objeto? Quem teve essa ideia infeliz?

Eu poderia colocar essa pergunta como um ageísmo, mas eu prefiro o tempo esnobismo cronológico. Mas você está certo! Na minha humilde opinião, essa ideia é infeliz! Hoje nós sabemos disso porque a experiência desenvolvendo na linguagem Java nos mostrou isso. Quando ela foi desenvolvida a crença comum era de que Orientação Objeto era a panaceia para todos os males da computação. Se quiser reclamar, pode! Mas lhe garanto que não foi a pior ideia envolvendo OO, tentaram criar um banco de dados OO. Isso é bem pior do que escrever uma linguagem puramente OO.

Houveram projetos focados em fazer que componentes fosse a principal forma de desenvolvimento de software. Se acreditava que toda programação seria feita através do arrasto e do clique do mouse. Foi muito esforço para que não fosse mais preciso escrever código e nós estamos em 2022 escrevendo código. Quando o JavaBeans foi criado, a intenção era que ele pudesse ser manipulado por uma ferramenta visual, a BeanBox. Seria uma IDE que se conectaria vários componentes para que a dependência do desenvolvimento fosse reduzida. Como vemos pela história: deu errado! Mas esse esforço gerou muitas boas tecnologias que temos hoje.

Java Beans é uma especificação que deu origem ao que conhecemos hoje como Jakarta EE. É o falecido Java EE! É um modelo de programação em que seu código não fica dependente de um framework, da mesma forma que seu código não é dependente de uma máquina. Hoje é possível você escrever um programa para Quarkus e usar o mesmo código para OpenLiberty.

Já que falamos um pouco da história do Java, vamos começar a escrever nossa primeira linha Java?

Instalando tudo…​

Para desenvolver programas Java é preciso instalar a JDK. JDK é a sigla para Java Development Kit que são uma série de programas para compilar, empacotar e monitorar seu programa Java. Desde de 2017 o Java adotou um processo chamado Release Train, em que uma nova versão é lançada a cada 6 meses com as funcionalidades prontas, então não gaste tempo procurando qual versão instalar…​ Você precisa de apenas uma coisa: o SDKMan!. Com ele é possível instalar qualquer versão de Java que você deseja e algumas outras ferramentas como vamos citar mais a frente.

Outra habilidade importante é saber usar a linha de comando, você pode ser um desenvolvedor sem usar ela, mas eu recomendo ter um pouco de intimidade com o Bash e usar constantemente.

— Bash não é do Linux?! Eu uso Windows e não quero mudar meu sistema operacional!

Calma. Se você usa Windows…​ Tá errado! Brincadeira! hehehe Você pode usar Windows, eu mesmo uso Windows (não por livre e espontânea vontade). Para usar Bash no Windows você pode instalar o cliente GIT que ele já vem com uma ferramenta chamada Git Bash, um console MinGW que é um porte dos programas GNU para Windows.

GNU
GNU é um conjunto de programas que são criados pela comunidade de Software Livre. Software Livre é muito mais que Open Source, vale a pena conhecer mais a iniciativa Free Software Foundation que é responsável pelo GNU, é por causa dela que você não precisa pagar pra usar um compilador ou outras ferramentas que até sua criação eram pagas.

Para desenvolver, é recomendável que você use uma IDE. IDEs ou Integrated Development Environment (Ambiente de Desenvolvimento Integrado) são programas que integram editores de textos e ferramentas para desenvolvimento, build e analise de código. Escolha a que você mais gosta. Todas as IDEs relevantes no mercado tem suporte a Java.

— Ah, mas eu não posso usar o Notepad++?!?

Pode, mas você precisa de uma IDE porque é mais fácil desenvolver usando ferramentas. Elas provem funcionalidades que diminuem o número de bugs e facilitam o desenvolvimento como fazer a marcação da linguagem (o famoso code highlight) e para propor código (o famoso auto-complete). Desenvolvedores experientes preferem comodidade porque os problemas já são complexos demais para ficar perdendo tempo. Eu recomendo usar ou o Eclipse, o IntelliJ Idea ou o VS Code. As três IDEs são boas.

Usando uma IDE você pode construir seu projetinho Java, mas será muito difícil compartilhar ele com outras pessoas ou mesmo criar um executável a partir dele. Para facilitar a build do seu projeto existem ferramentas de gerenciamento de build: o Maven e o Gradle. Para instalar ele, procure no SDKMan!. Usando Maven/Gradle você pode definir o seu projeto e as dependências dele em um arquivo e ele será responsável pro baixar todas as dependências, compilar e gerar o que você precisa para colocar o seu software em produção.

Logo em resumo, o que você precisa é:

Construindo meu primeiro programa Java

Então agora que você sabe que o Java é mais que uma linguagem, vamos escrever nosso primeiro código Java?

Se você quiser aprender, recomendo abrir sua IDE preferida e criar um projeto Java. Tente explorar sua IDE, ela tem uma infinidade de recursos que muitas vezes são poucos conhecidos principalmente por desenvolvedores mais experientes. Vou demonstrar primeiro como criar usando o IntelliJ, depois usando o Eclipse e por fim usando o Gradle e o Maven. Se você deseja apenas estudar, sinta-se a vontade para usar apenas a IDE, mas se você usar um sistema de build será mais fácil você trabalhar em equipes e seu projeto terá uma aparência mais "profissional".

Usando o IntelliJ

Com o ItelliJ, selecione Novo Projeto e você verá a tela abaixo. Você precisa adicionar o nome do projeto (Name) e o local em que deseja criar o projeto (Location). Eu recomendo você ter uma pasta separada para todos os seus projetos.

intellij novo projeto 1
Figura 4. Tela de novo Projeto

Na tela acima, temos algumas opções que são importantes. A primeira delas é que você pode escolher o sistema de build do seu projeto. O IntelliJ já tem um sistema de build próprio, mas você pode usar Maven ou Gradle. A segunda opção é que você pode escolher a versão da JDK que você vai usar. A JDK é a ferramenta que te possibilitará desenvolver Java, ela contém todos os programas para compilar seu código, executar, debugar e muitas outras ferramentas que podemos falar mais a diante. O IntelliJ permite você selecionar a JDK e fazer o download dela. Eu recomendo você usar a versão mais recente e escolher a Oracle OpenJDK como vendor. Depois você pode escolher já inicializar esse projeto como um repositório git (Create Git repository) ou iniciar o projeto com um código de exemplo (Add sample code).

Depois de criado o projeto, você terá que adicionar uma classe ao projeto. Todo programa Java precisa de um método de entrada chamado main. Apesar de muitos criticarem essa limitação, isso era comum quando o Java foi desenvolvido. Hoje, na verdade, o Java não tem essa limitação, você pode usar o JShell e importar um arquivo jsh. Para criar sua primeira classe, selecione o botão direito do mouse na pasta src e depois selecione New → Java Class.

intellij novo projeto 2
Figura 5. Criando nova classe

Ao selecionar uma nova classe, será necessário dar um nome a ela. O nome de uma classe é o que chamamos de Fully Qualified Name, ele é composto pelo nome do pacote e o real nome da classe, no caso estou criando o pacote io.vepo.helloworld e a classe HelloWorld. Vamos falar mais sobre classes e pacotes quando formos falar de Orientação a Objetos (eu prometo falar disso, tenham paciência!).

intellij novo projeto 3
Figura 6. Dando nome a classe

Criada a classe, vou te apresentar uma funcionalidade muito importante. Abra o editor de texto posicione o cursor para editar o texto dentro da classe, adicione o texto ma e use a funcionalidade mais fabulosa que se chama auto-complete selecionando CTRL+SPACE! Magicamente a IDE vai compreender qual é o contexto e vai propor o que você deve escrever. Agora siga para o último snippet desse post. (snippet significa trecho, é normalmente um significado para um trecho de código que serve de exemplo simples).

intellij novo projeto 4
Figura 7. Criando método main

Usando o Eclipse

Eclipse é uma IDE que pode parecer ultrapassada, mas ela tem uma relação intrínseca com o Java, hoje uma nova versão do Java é liberado pela Oracle semestralmente, mas para que a Oracle conseguisse essa proeza (antes demorava anos) ela acabou deixando liberando o Java EE para Eclipse Foundation sob o nome de Jakarta EE. Por enquanto você não precisa saber de nada disso, só lembre que Eclipse é a IDE da Eclipse Foundation que controla alguma coisa do Java!

Porque eu citei o Java EE? Porque é provável que ao tentar fazer o download do Eclipse você veja a opção Enterprise como disponível. Você não precisa por enquanto de uma versão enterprise, tudo que você precisa é do Java Padrão (ou Java Standard Edition, SE para os mais íntimos).

Assim, ao iniciar o Workspace do Eclipse para Java você verá a opção para criar um novo projeto Java.

eclipse novo projeto 1
Figura 8. Criar novo projeto - Atalho

Ao selecionar, você entrará no Wizard de criação de um novo projeto. Semelhantemente ao IntelliJ, você terá que escolher um nome para o projeto e um local, a diferença é que no Eclipse o local padrão é o workspace. Você não precisa criar o projeto no workspace, você pode usar qualquer diretório, mas será no workspace que o Eclipse salvará alguns arquivos que definem como você está usando o mesmo, por isso caso você tenha mais de um contexto de desenvolvimento, você pode usar vários workspaces e trocar quando necessitar trocar de contextos. Por exemplo, você tem o workspace do trabalho e o workspace da faculdade, ou um workspace para cada projeto que você está trabalhando.

Você também pode selecionar a JDK que vai usar. Eu recomendo selecionar Finish, pois as outras telas do wizard são usadas para adicionar novas bibliotecas ou mudar a estrutura de diretórios do projeto.

eclipse novo projeto 2
Figura 9. Criar novo projeto - Wizard

Da mesma forma que o IntelliJ você tem que selecionar o botão direito do mouse na pasta src e depois selecione New → Java Class.

eclipse novo projeto 3
Figura 10. Criando classe - Atalho

E por fim dar um nome a classe, mas diferente do IntelliJ, o Eclipse dá mais liberdade para criar a classe, como já adicionar o método main.

eclipse novo projeto 4
Figura 11. Criando classe - Wizard

Com a classe, você também pode usar o auto-complete. Eu pessoalmente acho essa funcionalidade melhor no Eclipse que no IntelliJ. Aliás, se você usa VS Code, você está usando essa funcionalidade porque o VS Code usa o servidor de código do Eclipse.

Uma desvantagem de usar eclipse é que ele não usa coordenadas Maven como veremos a seguir para definir as dependências.

Usando o Gradle

O erro mais comum de quem trabalha em grandes times é baixar uma IDE e criar um projeto Java. 🤯 Eu fiz isso por muito tempo, até descobrir que é só dor de cabeça. Quando fazemos isso acabamos por obrigar todo mundo do time a usar a mesma IDE e a ter que alterar arquivos de configuração complicados para fazer o projeto funcionar. Por isso, é mais fácil você usar o Maven ou o Gradle. Usar um sistema de build não significa não usar uma IDE, as IDEs conseguem importar a estrutura desses projetos e a partir daí toda as configurações serão feitas usando o sistema de build, mesmo se forem feitas através da IDE. A minha opção pessoal é o Maven, mas é por pura comodidade pois sou usuário há bastante tempo. Já tive vontade de aprender Gradle, mas…​ Bom…​ Vamos ver o Gradle!

O Gradle te permite gerar toda a estrutura do seu projeto automaticamente, basta executar gradle init no diretório da aplicação e seguir respondendo as perguntas. Eu recomendo criar uma application Java não quebrada em submódulos usando Groovy e JUnit Jupyter conforme as opções abaixo.

$ gradle init

Select type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 2

Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Scala
  6: Swift
Enter selection (default: Java) [1..6] 3

Split functionality across multiple subprojects?:
  1: no - only one application project
  2: yes - application and library projects
Enter selection (default: no - only one application project) [1..2] 1

  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 1

Select test framework:
  1: JUnit 4
  2: TestNG
  3: Spock
  4: JUnit Jupiter
Enter selection (default: JUnit Jupiter) [1..4] 4

Project name (default: meu-projeto-gradle):
Source package (default: meu.projeto.gradle):


BUILD SUCCESSFUL
2 actionable tasks: 2 executed

O próximo passo é abrir o diretório em uma IDE, ver a estrutura criada. Para saber como usar o Gradle, use o comando gradle tasks e com um pouco de Google Translator você poderá saber tudo o que fazer com o projeto.

Eu nunca tinha usado o Gradle e ele me parece bem mais fácil que o Maven. Você precisa ficar atento ao arquivo build.gradle que é onde todas as propriedades são definidas. Elas serão bem similares as definidas no nosso projeto Maven, mas em uma linguagem diferente, o Groovy.

Usando o Maven

Aviso
Apesar de Maven usar XML, não se sinta intimidado. Eu deixe um exemplo com comentários. Caso você ainda ache difícil, manda um feedback aí com a sua dificuldade pelo twitter para mim (@vepo).

Com o Maven você pode facilmente criar um projeto Java e compilar ele independente de IDE. O Maven também vai se encarregará de encontrar todas as dependências em suas versões e dependências. Então para criar um projeto Java basta criar um arquivo pom.xml e um arquivo Java, como na estrutura abaixo.

.
├── src
│   └── main
│       └── java
│           └── io
│               └── vepo
│                   └── helloworld
│                       └── HelloWorld.java
└── pom.xml

Para quem não conhece o Maven (dê uma olhada nesse simples tutorial), ele vai gerenciar a build do seu projetos Java. O arquivo pom.xml vai conter as informações básicas do projeto e as dependências. Você pode achar estranha a estrutura de diretórios, mas ela é bastante útil para evitar configurações. O Maven atua por um padrão chamado Convenção sobre configuração, ao invés de colocar todas as configurações do projeto, basta seguir essa regrinha básica de estrutura de diretórios.

Para encontrar dependências Maven, é possível procurar no mvnrepository.com. Cada dependência é definida pelas coordenadas groupId, artifactId e version e elas podem ser encontradas diretamente no mvnrepository.com, como é o caso do Kafka Clientes mvnrepository.com/artifact/org.apache.kafka/kafka-clients. Observe o padrão da URL, mvnrepository.com/artifact/{groupId}/{artifactId}. É possível também adicionar a versão na URL mvnrepository.com/artifact/{groupId}/{artifactId}/{version}. Isso facilita a busca pode dependências.

Para facilitar na execução, já estou colocando o plugin org.codehaus.mojo:exec-maven-plugin corretamente configurado para apontar para a classe io.vepo.helloworld.HelloWorld, assim para executar basta usar mvn clean compile exec:java.

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>

    <groupId>io.vepo.helloworld</groupId> <!-- Use um identificado para sua empresa                    -->
    <artifactId>hello-world</artifactId>  <!-- Use um identificado para seu projeto                    -->
    <version>1.0.0-SNAPSHOT</version>     <!-- Use um versão baseada em https://semver.org/lang/pt-BR/ -->
    <name>Hello World!</name>             <!-- Dê um nome legal ao seu projeto                         -->
    <properties>
        <!-- Caso você se uma versão de Java diferente, altere a linha abaixo -->
        <java.version>18</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.parameters>true</maven.compiler.parameters>

        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- Procure as dependências no mvnrepository.com -->
    </dependencies>
    <build>
        <finalName>hello-world</finalName> <!-- Esse nome é usado para construir o jar final -->
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <mainClass>io.vepo.helloworld.HelloWorld</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Observe como é simples…​ Com isso todas as configurações ficam disponíveis em um único arquivo que pode ser usado pela sua IDE preferida.

Agora é só criar a classe como o exemplo abaixo e pronto! Execute mvn clean compile exec:java e você verá o resultado na tela.

package io.vepo.helloworld;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

Agora caso você queira criar um programa usando um framework…​ Eu recomendo você procurar o tutorial desse framework. Talvez você precisará escrever um main específico ou mesmo usar um conjunto de anotações, adicionar uma série de dependências e um plugin.

Exercícios

Os exercícios são propostos como forma de validar que você pode ir para o próximo passo. Nessa sessão vamos apenas pedir para você configurar o ambiente, para isso:

  1. Configure usa IDE preferida

  2. Crie um programa Java usando a IDE

  3. Crie um programa Java usando um sistema de build (Maven ou Gradle)

  4. Tente criar um programa linha de comando usando os código de escape ANSI. Você pode fazer usando o System.out.println ou uma biblioteca (por exemplo a github.com/fusesource/jansi)

  5. [Opcional] Tente criar e rodar um projeto Spring Boot usando o Spring Initializr

  6. [Opcional] Tente criar e rodar um projeto Quarkus usando o Quarkus - Start coding with code.quarkus.io

  7. [Opcional] Tente criar e rodar um projeto Microprofile.io usando Starter | MicroProfile

Próximos passos

Agora que você sabe como escrever e executar um programa Java, você pode conhecer um pouco mais da sintaxe da linguagem. Ela é baseada na linguagem C, mas tem algumas especificidades…​ Eu recomendei o tutorial do W3CSchools por ter ao menos uma listagem das principais construções do Java 8. Tente saber como declarar uma classe, um método, variáveis, quais são as principais estruturas de loop (for e while) e suas variações e por fim as estruturas lógicas (if e switch).

Depois conheça ao menos alguns dos pacotes básicos da linguagem, a documentação está disponível na internet. Eu recomendo que você comece pelo pacote java.util ele vai conter as classes básicas de coleções. No próximo post vamos focar exatamente nela!

Originally published April 29, 2022