Guia de Linguagem

Linguagem Java


Neste Guia de Referência você encontrará todo o conteúdo que precisa para começar a programar com a linguagem Java, a sua caixa de ferramentas base para criar aplicações com Java.

A plataforma Java

Você já deve ter ouvido falar que Java é tanto uma linguagem quanto uma plataforma. Isso quer dizer que, além da linguagem, o programador Java também conta com um conjunto de APIs que facilitam o desenvolvimento ao oferecerem soluções para situações comuns de desenvolvimento.

Confira como a plataforma Java foi organizada para atender as necessidades de diferentes tipos de aplicações:

  • Java SE: Representa a base do Java, sendo composta pelas APIs e bibliotecas básicas para possibilitar o desenvolvimento de aplicativos de linha de comando e desktop. Já ouviu falar em Swing? Sim, ele faz parte do Java SE (Java Standard Edition);
  • Java ME: A Java Micro Edition é a plataforma voltada para dispositivos móveis e embarcados, com capacidade de processamento reduzida, como os utilizados na criação de produtos para a Internet das Coisas;
  • Java EE: Voltada para o desenvolvimento de soluções web e corporativas, a Java Enterprise Edition é uma especificação que agrupa outras, sendo, por isso, conhecida como especificação “guarda-chuva”.

Aprenda mais sobre a plataforma Java no artigo:

Máquina Virtual Java

Na máquina virtual Java, ou JVM, é onde a sua aplicação será executada. É ela, também, a responsável pela característica multiplataforma do Java. Um programa escrito nessa linguagem será executado em qualquer plataforma, seja ela um notebook, smartphone ou torradeira, que possua uma máquina virtual Java implementada.

Um dos recursos mais conhecidos da JVM é o Garbage Collection. É ele que é acionado com certa frequência para limpar da memória objetos que não estão sendo utilizados, evitando desperdício de espaço e que sua aplicação deixe de funcionar por falta dela. Para se aprofundar neste assunto preparamos os seguintes artigos:

Algumas vezes, a depender da proposta de sua aplicação, pode ser necessário fazer customizações na JVM visando melhoria na performance. Para aprender sobre isso, acesse:

Primeiros passos

Assim como em qualquer outra linguagem, no Java você encontrará tópicos de conhecimento fundamental. Dominá-los permite programar um código mais limpo e fácil de ser compreendido.

Diferente de outras linguagens, no Java o seu primeiro código será escrito dentro de um método de uma classe. Pensando nisso, nada melhor que começar pela criação da sua primeira classe Java. Saiba mais no artigo:

Após aprender sobre classes você deve estar curioso para saber como declarar variáveis e realizar operações com elas. Acompanhe esses próximos passos nos posts:

No Java as enums são um poderoso recurso para a criação de objetos imutáveis. Saiba mais sobre elas nos posts:

Você já ouviu falar que tudo no Java são objetos? Se ainda não, não tem problema. Os artigos a seguir te deixarão por dentro desse assunto:

Agora que você já conheceu os componentes básicos de um programa Java, que tal olhar um pouco mais de perto a criação de uma classe? Confira neste 5 minutos:

Strings

A manipulação de texto é algo bastante comum no desenvolvimento de aplicações. Em Java, a estrutura principal para isso é a classe String, que nos fornece vários métodos para sua manipulação. Nos posts abaixo você encontrará conteúdos que abordam desde os métodos básicos, até outras opções para que possa manipular texto da maneira mais adequada para sua solução.

Além da classe String, temos também as classes StringBuilder e StringBuffer. Para aprender sobre elas e as diferenças em relação à String, acesse:

Algumas vezes precisamos de uma ferramenta mais específica para processar Strings. É nesse momento que as expressões regulares podem ajudar. Saiba mais neste artigo:

Estruturas de condição e repetição no Java

Duas ferramentas importantes e presentes na lógica de programação de qualquer código são as estruturas de condição e repetição. A estrutura de condição nos permite criar um bloco de código a ser executado apenas se determinada condição for atendida. Já a estrutura de repetição nos permite criar um bloco de código que pode ser executado várias vezes, enquanto a condição especificada for verdadeira.

Aprenda sobre essas estruturas nos posts abaixo:

Entrada e saída de dados

Saber apresentar dados na tela e ler dados do teclado é um passo fundamental no aprendizado da programação. Lembre-se que o principal objetivo de um programa é processar os dados do usuário e exibir os resultados. Para isso temos os recursos de Entrada/Saída, ou In/Out da linguagem. Aprenda sobre eles nos posts abaixo:

Módulos do código Java

Saber como organizar o código é fundamental para sua manutenção e reutilização. Em Java, o código é organizado em pacotes, classes e métodos. Dominados esses conceitos, e utilizando modificadores de acesso, podemos controlar como cada classe ou método poderá ser reaproveitado pelos demais. Para aprender sobre isso, acesse o conteúdo abaixo:

Estrutura de Dados

Ao começar a desenvolver sistemas um pouco mais avançados, você se deparará com a necessidade de organizar os dados que são manipulados no código. Para isso, é comum o uso de estruturas de dados, que, como o nome indica, fornecem uma forma padrão para agrupar e simplificar a gerência de dados com características em comum. Os links abaixo trazem um conteúdo que possibilitará um detalhamento sobre esse tema:

Tratamento de exceções

É comum a ocorrência de exceções durante a execução de um programa. O que não é comum é não nos prepararmos para elas. Uma exceção é um evento diferente daquilo que normalmente o software espera que aconteça. Quando não tratamos exceções, o software fica sem saber o que fazer com ela e como continuar sua execução, o que normalmente leva à paralisação do sistema. Para aprender a tratar exceções, acesse:

Todo programa pode e vai falhar em algum momento. Aplicações consistentes se preparam adequadamente para esse momento. Aprenda no curso abaixo como isso é possível com tratamento de exceções:

Serialização e fluxo de dados

Logo você poderá se perguntar: Como salvar os dados que utilizo em minha aplicação para que consiga utilizá-los posteriormente? A resposta é simples: Serialização. Quando serializamos um objeto, estamos o transformando em um array de bytes, formato utilizado para salvar arquivos.

Os artigos abaixo o ensinarão a fazer isso:

Agora, se você deseja aprender como salvar os dados em um banco de dados, consulte o Guia de Referência Carreira Programador Java e veja outros conteúdos sobre a linguagem.

Sockets

Caso seu interesse seja aprender como enviar e receber dados e arquivos pela rede, saber programar com Sockets é fundamental. Compreender sockets é a primeira etapa para iniciar na programação distribuída. Para dominar esse assunto, acesse:

Threads

Com a multiplicação do número de núcleos presentes em um processador, saber como programar com threads é algo de grande relevância para fornecer sistemas com alto desempenho, que explorem ao máximo o poder computacional de servidores e desktops. Aprenda sobre esse assunto com os links abaixo:

Collections

Neste momento é bem provável que você já tenha tido o primeiro contato com as coleções, afinal, uma coleção é uma estrutura de dados. Mas, por que só agora falar delas? É importante compreender os fundamentos por trás de um conceito antes de começar a utilizar algo mais avançado, com um nível mais alto de abstração.

De forma simples, uma coleção é uma lista de objetos. Como quando lidamos com dados é comum nos depararmos com diferentes necessidades de organização dos mesmos, o Java facilita esse trabalho nos fornecendo diferentes opções para mantê-los - de listas que se preocupam apenas em armazenar os dados em memória, a listas que evitam dados repetidos e os mantém ordenados.

Nos links abaixo você aprenderá como e quando adotar cada uma:

Generics

Generics é uma importante funcionalidade da linguagem Java que foi criada para facilitar o reuso do código e tornar a implementação mais segura e menos propensa a erros. Generics são bastante utilizados quando lidamos com coleções, por exemplo, e sua declaração é feita com os caracteres ‘<>’. Assim, quando declaramos uma lista, podemos especificar que essa lista somente poderá receber objetos de um tipo.

Com isso, caso o programador tente inserir um objeto de tipo diferente, o erro será identificado em tempo de compilação, e não mais em tempo de execução. Para aprender sobre Generics, acesse:

Expressões Lambda

Um dos recursos mais jovens da linguagem Java agrega um toque de programação funcional a ela. Uma definição simples e um pouco abstrata é entender que uma expressão lambda é uma opção para programar uma função sem que para isso seja necessário declarar um nome e um tipo de retorno. Em geral, a expressão lambda é declarada no mesmo lugar em que será utilizada e possibilita um código menor e mais simples de manter.

A sintaxe de uma expressão lambda é bastante simples. Começamos declarando os parâmetros. Em seguida utilizamos o operador arrow. Por fim, declaramos o bloco de código a ser executado.

(Zero ou mais parâmetros) -> { /* bloco de código */ }

Para se aprofundar nesse assunto, acesse:

Streams

Com o intuito de aprimorar a forma como manipulamos coleções de dados, o Java 8 trouxe a Streams API, conjunto de classes e interfaces que faz uso de conceitos da programação funcional e das expressões lambda para que escrevamos código mais claro e em menor quantidade.

Para isso, obtemos uma stream, a partir de uma coleção, por exemplo, e, sem nos preocuparmos com a forma como os dados serão percorridos, programamos algum tipo de processamento sobre os dados, como filtros, mapeamentos, entre outros, já fornecidos pela API.

Como exemplo, considere que temos uma lista de produtos e desejamos selecionar apenas aqueles cujo valor seja maior do que 5. O código para solucionar esse problema poderia ser:

List<produto> produtosFiltrados = produtos
  .stream()
  .filter((p) -> p.getValor() > 5)
  .collect(Collectors.toList());

Reflection

O Java também dispõe de um recurso conhecido como Reflection. Com ele, em tempo de execução conseguimos acessar informações de uma classe, como os atributos e métodos, assim como instanciar essa classe e invocar um método. Isso nos permite estender funcionalidades de uma aplicação, por exemplo.

Mas antes de prosseguir, sem querer dar spoiler, você vai precisar de um pouco de familiaridade com as anotações em Java para entender esse poderoso conceito na prática. Saiba mais no artigo:

Reflection também é muito utilizado por IDEs, bibliotecas e frameworks, os quais precisam lidar com classes criadas por terceiros. Você já imaginou como aquela biblioteca que faz o parsing de objetos para JSON e vice-versa funciona? Como ela consegue converter qualquer objeto para JSON e o JSON para seu respectivo objeto? Via Reflection! :)

Para aprender sobre ele e saber como aplicar esse avançado recurso em alguns dos seus projetos acesse:

Orientação a objetos

A Orientação a Objetos é o paradigma de programação mais utilizado para o desenvolvimento de sistemas e tem como principal característica o planejamento e implementação do software a partir da representação de ‘coisas’ da vida real por meio de objetos.

Antes desse paradigma era comum criarmos sistemas utilizando o paradigma de programação estruturada. Porém, devido a limitações, aos poucos essa opção começou a ser substituída.

Conheça algumas das vantagens da Orientação a Objetos nos DevCasts:

Para compreender as diferenças entre a Programação Orientada a Objetos e a Estruturada, acesse:

Em Java, por uma "coincidência planejada" :), tudo são objetos, o que reforça ainda mais a relação entre a linguagem e esse paradigma. Portanto, se você pretende se tornar um bom programador Java, aprender Orientação a Objetos (OO) é fundamental. E agora, o que faço? Não se preocupe, os conteúdos abaixo ensinarão tudo o que você precisa para isso:

Pilares da Orientação a Objetos

Ao planejar a programação baseada em objetos, esse paradigma trouxe consigo uma série de conceitos, os quais levam a um código mais fácil de entender, manter e reutilizar. Esses conceitos são a abstração, encapsulamento, herança e polimorfismo, introduzidos no link abaixo:

Saiba mais sobre esses conceitos nos artigos:

O encapsulamento é o pilar da Orientação a Objetos que nos permite ocultar informações e, ao mesmo tempo, atribuir segurança ao código. Quando encapsulamos o acesso a uma variável, por exemplo, não importa para o objeto que consome essa informação (o cliente), se o valor é obtido lendo o dado em memória ou se foi necessário acessar um banco de dados.

Imagine que você esteja em um restaurante e faça um pedido. É importante para você saber qual panela está sendo utilizada, a ordem de preparo dos nutrientes, entre outras coisas? Então, encapsular é a "arte" de deixar acessível ao cliente apenas aquilo que ele precisa saber. Para aprender mais sobre isso, acesse:

E a herança? Como assim programar uma herança? Você herdou características de seus pais, avós e de outras gerações passadas, não é mesmo? Na Orientação a Objetos, quando precisamos fazer com que a classe B possua características de outra, definimos via código que a classe B herda dessa outra. Interessante, não? :) Ainda está achando um pouco confuso? Acesse o post:

O polimorfismo é um pilar da Orientação a Objetos que tem forte ligação com a herança. Algumas vezes, quando herdamos uma característica, precisamos adicionar a ela um comportamento diferente. Por exemplo: todo animal sabe correr, porém, cada um corre de uma maneira diferente. Para aprender como utilizar polimorfismo em Java, acesse:

Ao aplicar corretamente esses conceitos você terá como resultado um código eficiente, de fácil manutenção e reuso. Saiba que um código de qualidade não envelhece e você poderá reutilizá-lo em vários projetos. O post abaixo retrata esse assunto.

Coesão e acoplamento

Você já deve ter ouvido falar que um bom código precisa ter alta coesão e baixo acoplamento. No entanto, o que é a coesão e o acoplamento? A coesão é uma medida que indica quão bem delimitado está cada módulo do nosso código. Caso ele faça mais coisas do que deveria, dizemos que temos um módulo com baixa coesão. Já o acoplamento mede o grau de dependência de um módulo em relação aos demais. Caso ele dependa de muitos módulos, dizemos que ele está com acoplamento alto. Essas situações devem ser evitadas, pois tornam o código muito mais difícil de manter e evoluir.

Para aprender mais detalhadamente sobre esse assunto, acesse:

Princípios SOLID

Após compreender os pilares da Orientação a Objetos na teoria e na prática, um importante passo na busca pelo código de qualidade é aprender sobre os princípios SOLID.

Esses princípios nos ajudam a pensar no problema a ser modelado de forma orientada a objetos, propondo definições que nos levam a um design de código coeso e com baixo acoplamento, o que o torna fácil de ler, manter e reutilizar.

E por que esse nome, por que SOLID? Esse termo é um acrônimo para as cinco "regras" que o compõem:

  • S - Single Responsibility Principle - O Princípio da Responsabilidade Única define que cada classe deve ter apenas uma responsabilidade;
  • O - Open Closed Principle - O Princípio do Aberto Fechado define que uma classe deve ser extensível (aberta para extensões) por outras classes, sem que para isso precise ser modificada (fechada para modificações);
  • L - Liskov Substitution Principle - O Princípio da Substituição de Liskov está relacionado ao uso da herança e dita que devemos ser capazes substituir a classe filha pela classe pai sem que o funcionamento do software seja prejudicado;
  • I - Interface Segregation Principle - O Princípio da Segregação de Interfaces preza pela correta definição de interfaces, de forma que os clientes que a consumam tenham acesso apenas àquilo que de fato é necessário;
  • D - Dependency Inversion Principle - O Princípio da Inversão de Dependências sinaliza que devemos depender apenas de classes abstratas, e não de classes concretas;

Para se aprofundar de fato nesse assunto, acesse os posts abaixo.

Orientação a Objetos na prática

Agora que você já conhece os pilares da Orientação a Objetos, que tal pôr as mãos na massa? Pode dizer! Já estava na hora, não é mesmo? :)

Para isso reunimos uma seleção de artigos que abordam esse tema na prática. Confira abaixo:

Como apoio a esse conteúdo, não deixe de verificar os posts abaixo e aprenda como solucionar e/ou evitar os erros mais cometidos quanto adotamos o paradigma OO.

Boas práticas

Até o momento você aprendeu as principais tecnologias que compõem o Java, bem como utilizá-las de forma consistente. Que tal agora colocar em prática esses conhecimentos enquanto aprende técnicas avançadas no desenvolvimento com Java? Saiba como no curso:

Lembre-se que o aprendizado da linguagem Java precisa ser constante. Somente programando você conseguirá implementar códigos melhores. Os links abaixo te ajudarão a enriquecer esse conhecimento e agregar valor e qualidade às suas soluções:

Ao prosseguir com a busca pelo código de qualidade, em algum momento você se deparará com o termo Clean Code. Mas, o que é isso? O Clean Code, ou Código Limpo, reúne uma série de práticas a serem aplicadas para obter um código fácil de compreender e evoluir.

A qualidade do código também influencia na performance. Para conhecer algumas opções que te ajudarão a aprimorar o desempenho de suas aplicações, acesse:

Mais sobre Java

Além dos cursos e exemplos sugeridos nesse guia, a DevMedia publica com frequência novos conteúdos sobre Java, os quais você pode conferir nos Guias de Consulta abaixo:

Além disso, você pode conferir todo o conteúdo de Java clicando aqui.

Ficou com alguma dúvida?