Buscar

programacao_orientada_a_objetos_i (1)

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 150 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 150 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 150 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Programação Orientada a Objetos I
VINÍCIUS GODOY
Código Logístico
58878
Fundação Biblioteca Nacional
ISBN 978-85-387-6531-8
9 7 8 8 5 3 8 7 6 5 3 1 8
A orientação a objetos representou uma revolução na 
forma de construir softwares. Desde que 
se popularizou, em torno dos anos 1990, se 
tornou parte das principais linguagens de 
programação utilizadas no mercado, como 
Java, C++ e C#. Ela permitiu a divisão 
de programas em partes menores e 
reutilizáveis e a construção de 
sistemas cada vez mais complexos. 
Não é à toa que hoje é utilizada 
em programas não só em computadores e 
laptops, mas também em celulares, tablets e 
até mesmo em carros e geladeiras. 
Programação orientada 
a objetos I
IESDE
2019
Vinícius Godoy
Todos os direitos reservados.
IESDE BRASIL S/A. 
Al. Dr. Carlos de Carvalho, 1.482. CEP: 80730-200 
Batel – Curitiba – PR 
0800 708 88 88 – www.iesde.com.br
© 2019 – IESDE BRASIL S/A. 
É proibida a reprodução, mesmo parcial, por qualquer processo, sem autorização por escrito do autor e do detentor dos 
direitos autorais.
Projeto de capa: IESDE BRASIL S/A.
Imagem da capa: IESDE BRASIL S/A.
CIP-BRASIL. CATALOGAÇÃO NA PUBLICAÇÃO 
SINDICATO NACIONAL DOS EDITORES DE LIVROS, RJ
M497p
Godoy, Vinícius
Programação orientada a objetos I / Vinícius Godoy. - 1. ed. - Curitiba [PR] : 
IESDE Brasil, 2019.
146 p. : il.
Inclui bibliografia
ISBN 978-85-387-6531-8
1. Java (Linguagem de programação de computador). 2. Programação orientada a 
objetos (Computação). I. Título.
19-60075 CDD: 005.117
CDU: 004.43
Vinícius Godoy
Mestre em Visão Computacional pela Pontifícia Universidade Católica do Paraná (PUCPR), 
especialista em Desenvolvimento de Jogos de Computadores pela Universidade Positivo (UP) 
e graduado em Tecnologia em Informática pela Universidade Tecnológica Federal do Paraná 
(UTFPR). Trabalha na área de informática desde 1997, tendo participado de grandes projetos, 
como a edição de 100 anos do Dicionário Aurélio Eletrônico. Também atua como moderador do 
GUJ, o maior fórum de tecnologia Java do Brasil.
Sumário
Apresentação 7
1 Olá, Java! 9
1.1 Breve histórico 9
1.2 Arquitetura da plataforma 10
1.3 Instalando o ambiente 12
1.4 O primeiro programa Java 16
2 Conhecendo a linguagem 25
2.1 Variáveis e tipos de dados 25
2.2 Controle de fluxo: estruturas de decisão 34
2.3 Controle de fluxo: estruturas de repetição 36
2.4 Escopo de variáveis 39
3 Classes e objetos 43
3.1 Classes e objetos no mundo real 43
3.2 Sua primeira classe 45
3.3 A palavra-chave static 51
3.4. O valor especial null 54
4 Compondo objetos 57
4.1 Classificação no mundo real: o todo e suas partes 57
4.2 Associando objetos 59
4.3 Pacotes 61
4.4 Encapsulamento e modificadores de acesso 63
4.5 Referência a valor 66
5 Hierarquias de classes 71
5.1 Classificação no mundo real: biologia 71
5.2 Apresentando o problema 73
5.3 Herança 77
5.4 Polimorfismo 81
5.5 Classes e métodos abstratos 83
5.6 Interfaces 84
6 Generics e lambda 89
6.1 O que são generics 89
6.2 Generics 91
6.3 Lambda 94
7 A biblioteca de coleções 101
7.1 Listas 101
7.2 Conjuntos 105
7.3 Mapas 111
7.4 Streams 112
8 Tratamento de erros 117
8.1 Entendendo o problema 117
8.2 Disparando exceções 120
8.3 Capturando exceções 124
Gabarito 133
Apresentação
Prezado aluno,
Neste livro, você começará a desvendar o paradigma orientado a objetos. Ainda me lembro 
quando, no ano de 1997, um dos meus professores da universidade nos mostrou "um novo recurso 
de programação que talvez cole". Pela primeira vez, fui apresentado ao conceito de classes, descobri 
uma nova forma de programar. Fiquei deslumbrado, em meio a colegas meio céticos, com como 
aqueles recursos permitiam resolver problemas de uma maneira muito mais natural. 
Foi nesse mesmo ano que conheci uma plataforma de programação que prometia se destacar 
pela forte integração com outra tecnologia ascendente: a internet. Essa plataforma era o Java, que 
apresentava uma máquina virtual, tornando-a compatível com vários sistemas operacionais ao 
mesmo tempo. Seus críticos alegavam que isso tornava a linguagem muito lenta, que consumia 
muita memória e que ela jamais ganharia força no mercado.
Hoje, a orientação a objetos se tornou o padrão da indústria e aquela plataforma de 
programação sobreviveu em meio a vários concorrentes. Isso mostrou o quão acertada estava a 
visão de seus criadores, que miraram em necessidades do futuro, prevendo a evolução tecnológica 
do hardware e da rede mundial de computadores. A cada ano, a relevância da plataforma cresceu: 
conquistou os servidores de internet e os dispositivos móveis Android e passou a ser parte da ementa 
de praticamente todas os cursos de informática. Sua máquina virtual tornou-se extremamente veloz 
e moderna, um conjunto de classes e recursos bastante robustos foi apresentado e uma comunidade 
se organizou para propor melhorias na plataforma e mantê-la elegante e fiel a seus princípios. 
Ao escrever esse livro, além da orientação a objetos, procurei gerar um material atualizado, 
com vários detalhes e recursos da última versão disponível do Java. Além disso, complementei o 
material com dicas de programação, vindas tanto de livros e materiais de referência internacionais 
quanto diretamente do cotidiano de um programador. Espero que você aprecie o material e, assim 
como o jovem Vinícius, se deslumbre e transforme sua forma de programar.
Pronto?! Hora de embarcar nessa jornada...
1
Olá, Java!
Em nosso livro de programação orientada a objetos, iremos utilizar a plataforma Java. O Java 
é a linguagem presente em servidores de internet e em celulares Android. Neste primeiro capítulo, 
aprenderemos o que é a plataforma e como ela está organizada, instalaremos o ambiente e você 
conseguirá compilar e executar seu primeiro programa em Java. Pronto para aprender um pouco mais?
1.1 Breve histórico
Em dezembro de 1990, um time de 13 engenheiros da Sun Microsystems, liderado por James 
Gosling, Mike Sheridan e Patrick Naughton, iniciou o desenvolvimento do Projeto Green, com o 
objetivo de desenvolver uma plataforma que representaria a próxima onda tecnológica do mundo. 
Na visão deles, pessoas poderiam controlar diversos dispositivos, como TVs e telefones, de maneira 
integrada (GOSLING, 1998).
O time focou-se no desenvolvimento de um PDA, uma espécie de tablet antigo, sem fio, capaz de 
executar animações e controlar vários dispositivos. Esse produto foi chamado de *7 (Star 7) e, embora 
não tenha chegado ao mercado, levou ao desenvolvimento de diversas tecnologias interessantes.
Uma delas foi a linguagem Oak, capaz de executar em diversos dispositivos, que 
posteriormente se tornaria a linguagem Java. Além da linguagem, uma grande biblioteca de 
software permitia que seus desenvolvedores fizessem animações, comunicassem via rede e 
realizassem várias operações no dispositivo de maneira mais fácil.
Quando o projeto começou a crescer, os projetistas logo perceberam o potencial da plataforma 
para a internet. O time trabalhou em um clone do navegador Mosaic, chamado WebRunner, que 
demonstrava o poder da tecnologia Java. Nele, era possível combinar e executar aplicações Java de 
maneira segura, em meio a páginas HTML e CSS. A tecnologia foi demonstrada na Conferência 
de Tecnologia, Design e Entretenimento, no início de 1995, em Monterey, capturando a atenção da 
audiência ao fazer o desenho de uma molécula em 3D se mover controlada pelo mouse (BYOUS, 
2004). Tal tipo de interação, comum hoje em dia, não era possível na internet daquela época.
Em junho de 1996, a primeira versão da plataforma Java foi oficialmente disponibilizada para 
o público, com a promessa de "escrever uma vez e rodar em todo lugar" (SUN MICROSYSTEMS, 
1996). Em 1997, a Sun tentou formalizar o Java, mas desistiu do processo, entretanto, isso fez com 
que ela criasse o Java Community Process (JCP), permitindo que modificações fossem propostas 
de forma pública e transparente. 
De novembro de 2006 até maio de 2007,a Sun tornou pública boa parte do código da 
Máquina Virtual Java, por meio da licença GPL. Nos anos de 2009 e 2010, a Oracle comprou a Sun 
Microsystems e passou a ser dona da tecnologia.
Programação orientada a objetos I10
Este material utilizará a versão 12 da linguagem Java, lançada pela Oracle em março de 
2019, que, mesmo após tantos anos, ainda respeita os princípios básicos dos designs originais 
(SUN MICROSYSTEMS, 1997):
• Simples, orientada a objetos e familiar;
• Robusta e segura;
• Neutralidade de arquitetura e portável;
• Alta performance;
• Interpretada, multithread1 e dinâmica.
É importante ter esses objetivos em mente, pois será mais fácil entender por que os projetistas 
da linguagem criaram determinados recursos.
1.2 Arquitetura da plataforma
Quando falamos em Java, é importante entender que não estamos nos referindo única e 
simplesmente a uma linguagem de programação. O Java é uma plataforma que inclui:
• Bibliotecas de classes: que permitem que você trabalhe facilmente com arquivos, interface 
gráfica, redes, entre outras funcionalidades.
• Ferramentas e utilidades: que envolvem ampla documentação, analisadores de 
performance e um empacotador de arquivos.
• Linguagem Java: que cobriremos intensamente nos demais capítulos do livro.
• Máquina Virtual Java: que explicaremos a seguir.
Todos esses elementos fornecem um ambiente poderoso, que permitirá que façamos 
aplicações comerciais robustas.
1.2.1 A Máquina Virtual Java (JVM)
Para que um programa de computador funcione, é necessário converter comandos em 
forma de textos como este:
print "Olá mundo!"
Em um código de máquina, muito específico e pouco legível, formado de milhares de 
instruções como estas:
AE 1F 91 AA 85 FF C4 1B 32 ...
Há duas formas de realizar essa tarefa (MENDONÇA, 2018):
• Por meio de um compilador, que traduz o programa inteiro, gerando um arquivo 
executável. Como esse programa já está na linguagem que o computador entende, sua 
execução é muito rápida.
1 Multithreading refere-se à capacidade de executar, em um único programa, várias tarefas ao mesmo tempo 
(GOETZ, 2018).
Olá, Java! 11
• Por meio de um interpretador, que traduz o software linha a linha, à medida que o executa. 
Como o processo de tradução ocorre enquanto o software é executado, a execução é mais 
lenta, o programador analisa o software.
Para você entender melhor essas ferramentas, vamos fazer uma analogia. Vamos supor 
que você seja o computador e que você só entenda a língua portuguesa. O programador escreveu 
o software em inglês. Um compilador seria análogo a um tradutor. Ele pegaria um livro inteiro 
(programa) e o traduziria para o português, de modo que você poderia ler o livro, sem a presença 
do tradutor ou mesmo do livro original. Já o interpretador seria equivalente a um intérprete, ou 
seja, à medida que ele lesse uma frase do livro, ele traduziria para você. Note que, para que isso seja 
possível, o intérprete precisa do livro original em mãos e precisa sempre estar presente. Por outro 
lado, esse processo é mais interativo, já que você pode tirar dúvidas com o intérprete.
Como um dos objetivos da plataforma Java sempre foi garantir uma execução segura e capaz 
de rodar no maior número de dispositivos possível, uma abordagem híbrida foi implementada (SUN 
MICROSYSTEMS, 1997). Nessa abordagem, o compilador Java (javac) transformará seu código no 
bytecode Java. Esse bytecode é um arquivo muito mais próximo da linguagem de máquina do que o 
código escrito em Java, mas ele ainda não pode ser diretamente executado pelo computador.
A execução final desse código, já otimizado, será realizada de maneira interpretada pela 
Máquina Virtual Java (JVM) instalada. A JVM possui habilidades bastante poderosas, como a 
capacidade de analisar trechos do bytecode mais utilizados e compilá-los de fato (compilação 
just-in-time). Além disso, por conhecer a plataforma onde o código está realmente sendo 
executado, a máquina virtual pode habilitar instruções específicas de modo a aproveitar ao 
máximo seus recursos.
A máquina virtual também pode garantir um ambiente de execução seguro, proibindo que 
programas maliciosos executem instruções que prejudiquem o computador (ORACLE, 1997). 
Além disso, pode fornecer ao programador diversas ferramentas para análise do código e medições 
de performance, tal como uma linguagem interpretada faria.
Figura 1 – Compilação e execução na plataforma Java
Compilador Empacotador
Execução do código 
final
Bytecode
compilado
programa.class
cadastro.class
Bytecodes
agrupados
programa.jar
Bytecodes
agrupados
programa.jar
Código-fonte 
programa.java 
cadastro.java
Execução
Compilação
Máquina 
Virtual Java
(JVM)
Fonte: Mendonça, 2018, p. 110.
Programação orientada a objetos I12
A desvantagem dessa abordagem é que o usuário final do programa precisa instalar a 
máquina virtual mesmo sem entender exatamente o que ela é. Outra desvantagem é que geralmente 
bytecodes são facilmente reversíveis em seu código-fonte original.
Finalmente, embora sejam consideravelmente mais rápidas do que as linguagens puramente 
interpretadas, esse processo tem impacto na performance que pode ser difícil de medir. Isso 
dificulta a criação de aplicações de tempo real, tais como reprodutores de vídeo ou jogos.
1.2.2 Como a plataforma é distribuída
A plataforma Java é distribuída em dois pacotes:
• Java Runtime Environment (JRE): é o pacote de execução. Contém apenas a JVM e o 
código compilado das bibliotecas padrão. Qualquer pessoa interessada em executar um 
programa Java deverá ter a JRE instalada em sua máquina.
• Java Development Kit (JDK): é o pacote de desenvolvimento. Contém o JRE em conjunto 
com o compilador Java, códigos-fonte, documentação e ferramentas. Deve ser instalado 
pelo desenvolvedor para criar projetos.
Você pode estar se perguntando: o que é o JEE? Não seria também um pacote, só que 
mais poderoso? JEE é a sigla de Java Enterprise Edition. Embora soe como uma versão "mais 
completa" do Java, não é disso que se trata. Ele é uma especificação sobre como diversos serviços 
adequados a aplicações de rede empresariais (como persistência, mensageria etc.) devem 
funcionar (ORACLE, 2019a).
A implementação desses serviços é feita por mais de 20 empresas terceiras (ORACLE, 2019b). 
Por exemplo, a JEE descreve a JPA (Java Persistence API), que descreve classes para uso de banco 
de dados. Tanto o Hibernate (Red Hat) quanto o Toplink (Oracle) são projetos que implementam 
essa especificação.
Graças ao JEE, é possível montar um servidor web com diversas tecnologias, de diversos 
fabricantes, comunicando entre si. Porém, o estudo do JEE está fora do escopo da nossa disciplina.
1.3 Instalando o ambiente
Antes de começarmos a desenvolver, precisaremos instalar todo o ambiente de 
desenvolvimento. Isto é, precisamos instalar o JDK, contendo compilador, Máquina Virtual Java, 
documentações e um editor de códigos, também chamado de ambiente integrado de desenvolvimento 
(IDE). Com esse ambiente em mãos, você poderá executar e testar os exemplos deste livro e resolver 
os exercícios propostos ao final de cada capítulo.
Olá, Java! 13
1.3.1 Instalação do JDK
Antes de começarmos a desenvolver, precisamos instalar o JDK. Para isso, entre no site 
Oracle (disponível em: https://www.oracle.com/technetwork/java/index.html). Você também 
pode usar o antigo site da Sun, que é muito mais fácil de decorar (disponível em: java.sun.com). 
Nele, clique em Java SE.
Figura 2 – Tela inicial do site Oracle
Fonte: Oracle.
Em seguida, clique no ícone do JDK.
Figura 3 – Página Java SE Downloads
Fonte: Oracle.
Programação orientada a objetos I14
Na parte inferior da tela, clique em Accept License Agreement e então escolha o instalador 
de acordo com sua plataforma, por exemplo, no caso do Windows:
Figura 4 – Aceitação do contrato de licença
Fonte: Oracle.
Siga o passo a passo do instalador e aguarde a conclusão do processo de instalação.
1.3.2 Instalando um IDE
Nós podemos escrevertodo o nosso código em editores de textos e executar a compilação 
manualmente, porém, esse é um procedimento tedioso, comparável a tentar escrever um livro 
usando somente o bloco de notas.
Ao longo dos anos, programadores criaram ambientes que nos auxiliam na codificação, 
chamados de Integrated Development Environment (IDEs). Esses ambientes fornecem ferramentas 
para análise do código, colorização de comandos, recurso de autocompletar inteligente, execução 
automática do código etc.
No caso do Java, existem três IDEs poderosos e gratuitos:
• Netbeans IDE, da Oracle;
• Eclipse, da Eclipse Foundation;
• IntelliJ IDEA, da Jetbrains.
Nós instalaremos o último. Para isso, acesse o site da empresa Jetbrains (disponível em: 
https://www.jetbrains.com/idea/) e clique em download.
https://www.jetbrains.com/idea/
Olá, Java! 15
Figura 5 – Página do IntelliJ IDEA
Fonte: JetBrains.
Dentre as opções, selecione a versão Community, que é gratuita:
Figura 6 – Escolha da versão
Fonte: JetBrains.
Rode o programa e siga o passo a passo da instalação. Cabe reforçar que os IDEs estão para 
o Java assim como o Word está para a língua portuguesa. Elas são apenas ferramentas para escrita 
de código, mas a linguagem de programação Java será a mesma nos três ambientes. Por isso, todo 
código presente neste livro poderá ser executado em qualquer um desses editores ou, até mesmo, 
diretamente na linha de comando.
Programação orientada a objetos I16
1.4 O primeiro programa Java
Vamos agora tentar criar e executar nosso primeiro programa em Java. Para isso, precisaremos 
abrir o IntelliJ e compreender a estrutura de um código bastante simples.
Na primeira vez que você abrir o IntelliJ, ele realizará algumas perguntas para a configuração 
básica. A primeira pergunta refere-se à importação das suas configurações. Como isso é possível 
somente se você já tiver instalado uma versão antiga do IntelliJ, simplesmente escolha a opção 
Do not import settings e siga em frente.
Figura 7 – Importação de configurações antigas
Fonte: IntelliJ IDEA.
Em seguida, o IntelliJ confirmará a sua licença de usuário. Basta confirmar que leu e clicar 
em Continue.
Figura 8 – Contrato de licença do IntelliJ
Fonte: IntelliJ IDEA.
Olá, Java! 17
A próxima tela pergunta se você deseja ou não enviar estatísticas de uso para a Jetbrains. 
O objetivo disso é tentar melhorar as futuras versões do IDE. Caso deseje, clique em Send Usage 
Statistics. Caso não deseje, use o botão Don't send.
Figura 9 – Compartilhamento de dados
Fonte: IntelliJ IDEA.
O próximo passo é escolher se você quer seu IDE no modo escuro ou claro. Muitos 
programadores consideram o modo escuro menos cansativo e mais interessante, por isso, ele já 
aparece selecionado no IDE. Escolha uma das opções e clique em Skip Remaining and Set Defaults. 
Isso pulará as demais configurações que são mais adequadas a usuários avançados.
Caso você tenha baixado a versão de avaliação do IDE, e não a versão Community, o último 
passo será fornecer suas credenciais. Faça isso caso você tenha uma conta Jetbrains ou escolha 
Evaluate for free caso você queira usar o período de avaliação.
Figura 10 – Ativação da licença da versão de avaliação
Fonte: IntelliJ IDEA.
Programação orientada a objetos I18
1.4.1 Criando o projeto
É hora de testar se tudo foi instalado corretamente escrevendo nosso primeiro programa 
Java. Para isso, abra o IntelliJ IDEA e clique em Create New Project.
Figura 11 – Criação de novo projeto
Fonte: IntelliJ IDEA.
No lado esquerdo, deixe selecionada a opção Java. Certifique-se também de que a versão do 
JDK seja a 12. Caso não seja, clique em New e selecione a pasta em que você instalou seu JDK. Em 
seguida, clique em Next. Não é necessário marcar nenhuma opção adicional.
Figura 12 – Escolha da linguagem
Fonte: IntelliJ IDEA.
Na tela seguinte, desmarque a opção Create Project From Template, se estiver marcada, e 
clique em Next.
Olá, Java! 19
Figura 13 – Criação de projeto em branco
Fonte: IntelliJ IDEA.
Nomeie o projeto como Aula1 e clique em Finish. O IntelliJ provavelmente perguntará se 
pode criar a pasta do projeto, clique em OK.
Figura 14 – Nome e caminho do projeto
Fonte: IntelliJ IDEA.
Uma tela como esta deverá se abrir:
Figura 15 – Seu primeiro projeto
Fonte: IntelliJ IDEA.
Programação orientada a objetos I20
Caso o menu esquerdo não se abra automaticamente, clique em 1: Project na barra lateral. 
O código-fonte do seu programa será colocado na pasta src. Ela aparece selecionada na captura de 
tela da Figura 15.
1.4.2 Escrevendo o código
Clique com o botão direito sobre a pasta src, clique em New e depois em Java Class. Dê o 
nome de Aula1 e clique em OK.
Figura 16 – New Java Class
Fonte: IntelliJ IDEA.
Observe que agora a pasta src contém um arquivo chamado Aula1. No disco, esse arquivo terá 
a extensão .java. E é nele que o código-fonte da nossa aplicação iniciará. Uma das regras da linguagem 
é que o nome do arquivo e da estrutura class, dentro dele, devem obrigatoriamente ser iguais.
Dentro desse arquivo, o seguinte código deve ter aparecido:
public class Aula1 {
}
Altere-o para:
Figura 17 – O primeiro programa
Fonte: elaborada pelo autor.
Você deve ter notado que, ao fazer isso, aparecem alguns botões verdes na barra lateral 
esquerda, ao lado da primeira e segunda linhas. Clique em um desses botões e selecione 
Run 'Aula1.main()'.
Olá, Java! 21
Figura 18 – Execução do primeiro programa
Fonte: IntelliJ IDEA.
Pronto! Você acaba de escrever e executar seu primeiro programa! Perceba que o resultado 
da execução já apareceu na parte inferior do IDE. É o texto "Olá mundo!".
Vamos agora analisar esse programa linha a linha:
1
2
3
4
5
public class Aula1 {
 public static void main(String[] args) {
 System.out.println("Olá mundo!"); //Imprime Olá mundo
 }
}
O Java é uma linguagem orientada a objetos. Isso quer dizer que você sempre trabalhará 
com o conceito de classes e objetos. Exploraremos em detalhes esses conceitos a partir do 
Capítulo 3, mas note que, desde a linha 1, já fomos obrigados a criar uma classe em que iremos 
trabalhar. Dentro dessa classe, definimos uma função importante, conhecida como função 
principal (main). Trata-se do ponto de entrada do nosso programa, declarado na linha 2. Tanto 
a classe quanto a função principal definem dois blocos de código delimitados pelas chaves {}.
Na linha 3, dentro da função main, imprimimos o texto "Olá mundo!", utilizando o 
comando System.out.println. Como o programa só tem essa linha, ele imprime esse texto e 
encerra. Observe que, logo após o comando, encontramos um comentário, criado por meio 
das duas barras //. Comentários são completamente ignorados na linguagem e nos permitem 
escrever anotações para nos acharmos no código. Poderíamos também criar comentários de 
várias linhas, bastando delimitá-los por /* e */.
Programação orientada a objetos I22
Observe que os comandos em Java são terminados pelo ponto e vírgula. Além dos 
comentários, as quebras de linha, a tabulação e os espaçamentos são ignorados pelo compilador, 
mas repare que os utilizamos para enfatizar os blocos de código. Essa prática é conhecida como 
endentação e recomendamos que você a siga durante o código. Alguns programadores, de outras 
linguagens inserem uma quebra de linha antes de abrir as chaves em cada bloco, o que deixaria 
nosso programa assim:
1
2
3
4
5
6
7
public class Aula1
{
 public static void main(String[] args)
 {
 System.out.println("Olá mundo!"); //Imprime Olá mundo
 }
}
Isso é perfeitamente permitido em Java, porém, embora sintaticamente correto, fere a 
convenção de código oficial (SUN MICROSYSTEMS, 1997), por isso, daremos preferência para a 
primeira forma.
Considerações finais
Neste capítulo, você aprendeu sobre a plataforma Java, sua importância e configurações. 
Juntamente com o primeiro programa, esse foi o primeiro passo para um aprendizado mais profundo.
No próximo capítulo, iniciaremos o estudo da linguagemJava. Inicialmente, conheceremos 
a estrutura básica, que será similar a qualquer outra linguagem que você já tenha estudado. 
Aproveite essa oportunidade para exercitar a linguagem de forma prática. Em seguida, estudaremos 
a orientação a objetos, uma forma de pensar em problemas na hora de escrever software.
A plataforma é um ótimo ambiente para esse aprendizado. Com um pouco de esforço e 
dedicação, tenha certeza de que cada hora de estudo será muito recompensadora.
Ampliando seus conhecimentos
• INTELLIJ IDEA. Default keymap. 2019. Disponível em: https://resources.jetbrains.
com/storage/products/intellij-idea/docs/IntelliJIDEA_ReferenceCard.pdf. Acesso em: 
4 ago. 2019.
Você pode conhecer um pouco mais sobre o IDE IntelliJ, com o qual iremos trabalhar. É 
bastante útil conhecer configurações e teclas de atalho. Por isso, consulte o cheat sheet, 
que contém um resumo das principais funções. Tenha esse documento em mãos, pois, 
com o tempo, esse uso será cada vez mais natural.
https://resources.jetbrains.com/storage/products/intellij-idea/docs/IntelliJIDEA_ReferenceCard.pdf
https://resources.jetbrains.com/storage/products/intellij-idea/docs/IntelliJIDEA_ReferenceCard.pdf
Olá, Java! 23
• MEYER, Maximiliano. Os melhores salários por linguagem de programação, 2018. Oficina 
da Net, 1 mar. 2018. Disponível em: https://www.oficinadanet.com.br/post/14518-qual-a-
linguagem-de-programacao-e-mais-bem-remunerada. Acesso em: 17 set. 2019.
Esse artigo dá um panorama do mercado de trabalho em 2018, envolvendo a linguagem 
Java e outras linguagens de programação. Observe que, embora o Java não tenha a 
melhor média salarial, apresenta o maior número de vagas disponibilizadas. Além disso, 
cabe lembrar que ele também é a linguagem do Android. Por fim, outras linguagens 
citadas no artigo, como o C# da plataforma .Net, também são orientadas a objetos. Por 
isso, ao aprender os conceitos deste livro, será fácil migrar para essas linguagens, caso 
você precise.
Atividades
1. O Java é uma linguagem híbrida. Por que isso é interessante? Quais são as desvantagens?
2. Na Seção 1.2, foi dito que o impacto de performance do Java é "difícil de medir". Discorra 
sobre o porquê dessa afirmação.
3. Quais são os cinco pilares de projeto da linguagem Java?
Referências
BYOUS, J. Java technology: the early years. The Internet Archive, 20 abr. 2004. Disponível em: https://web.
archive.org/web/20050420081440/http://java.sun.com/features/1998/05/birthday.html. Acesso em: 4 jul. 
2019.
GOETZ, B. Java concorrente na prática. Rio de Janeiro: Alta Books, 2018.
GOSLING, J. A brief history of the green project. The Internet Archive, maio 1998. Disponível em: https://web.
archive.org/web/20050609085739/http://today.java.net/jag/old/green/. Acesso em: 4 jul. 2019.
MENDONÇA, V. G. Introdução à computação. Curitiba: IESDE Brasil, 2018.
ORACLE. The Java Language Environment. 1997. Disponível em: https://www.oracle.com/technetwork/java/
intro-141325.html. Acesso em: 4 ago. 2019.
ORACLE. Java EE Compatibility. 2019a. Disponível em: https://www.oracle.com/technetwork/java/javaee/
overview/compatibility-jsp-136984.html. Acesso em: 4 jul. 2019.
ORACLE. Java EE at a Glance. 2019b. Disponível em: https://www.oracle.com/technetwork/java/javaee/
overview/index.html. Acesso em: 4 jul. 2019.
SUN MICROSYSTEMS. Javasoft Ships Java 1.0. The Internet Archive. 23 jan. 1996. Disponível em: 
https://web.archive.org/web/20070310235103/http://www.sun.com/smi/Press/sunflash/1996-01/
sunflash.960123.10561.xml. Acesso em: 4 ago. 2019.
SUN MICROSYSTEMS. Java Code Conventions. Oracle Technetwork, 12 set. 1997. Disponível em: https://
www.oracle.com/technetwork/java/codeconventions-150003.pdf. Acesso em: 4 ago. 2019.
2
Conhecendo a linguagem
Neste capítulo, iremos explorar rapidamente a sintaxe básica da linguagem Java. 
Entenderemos como as declarações de variável funcionam e veremos as principais estruturas 
de controle para tomada de decisão e repetição. Ainda veremos a linguagem do ponto de vista 
estruturado, sem focar na parte orientada a objetos – essa segunda parte será tema do próximo 
capítulo. Apesar de ser um capítulo longo, você não terá dificuldades para acompanhar o assunto 
se já conhecer outras linguagens de programação.
Considere que todos os exemplos que veremos adiante estão contidos no interior do bloco 
de código da função principal. Por exemplo, se mostrarmos o código:
1
2
int x = 10;
System.out.printf("O valor de x é: %d%n", x);
Você só conseguirá executar esse exemplo caso inclua todo o código extra exibido no capítulo 
anterior, ou seja, você precisaria criar o arquivo Aula2.java e, então, digitar dentro dele o seguinte:
public class Aula2 {
 public static void main(String[] args) {
 var x = 10;
 System.out.printf("O valor de x é: %d%n", x);
 }
}
Embora esse código extra possa parecer excessivo, você logo verá que ele ocorre de maneira 
natural em programas maiores.
2.1 Variáveis e tipos de dados
Java é uma linguagem fortemente tipada. Isso quer dizer que as variáveis estarão associadas 
a um único tipo de dado durante toda a sua existência. Esse tipo de dado indica a informação que a 
variável armazenará e quais operações poderemos realizar sobre ela. Os principais tipos de dados, 
de acordo com Oracle (2017a), são:
• Tipos primitivos:
• Booleano (verdadeiro/falso): boolean.
• Inteiros: byte, short, int e long.
• Numéricos decimais: float e double.
• Texto: char.
Programação orientada a objetos I26
• Tipos não primitivos: 
• String.
• Enumerações.
• Arrays.
• Referências para objetos: declaradas sempre que usamos uma classe.
Há duas formas de declarar variáveis, a primeira é com a tipagem explícita, em que 
indicamos o tipo diretamente nas formas:
tipo nomeDaVariavel;
tipo nomeDaVariavel = valor;
Para definirmos uma variável textual que guardará um nome, por exemplo, poderíamos 
fazer:
String nome;
Ou poderíamos definir uma variável inteira para indicar o número de páginas de um livro já 
inicializada com o valor 100, na seguinte forma:
int paginas = 100;
Também é possível declarar mais de uma variável de mesmo tipo em uma única linha, 
separando-as por vírgula. Por exemplo:
int x = 10, y = 20;
Embora isso seja possível, não é muito usual, pois a sintaxe pode ser confusa (SIERRA; 
BATES, 2010). A linha a seguir, por exemplo, declara a variável x sem valor e a variável y com o 
valor 50, não as duas variáveis com valor 50, como pode parecer:
int x, y = 50;
Por isso, muitos programadores consideram uma boa prática declarar cada variável em sua 
própria linha.
Além da maneira explícita, podemos declarar variáveis utilizando tipagem implícita, por 
meio da instrução var. Nesse caso, seremos obrigados a indicar o valor, pois é por meio dele que 
o Java determinará o tipo da variável. Note que a variável ainda tem um tipo, o qual não poderá 
mudar. 
Por exemplo, a variável páginas poderia ser declarada de maneira implícita:
var paginas = 100;
Conhecendo a linguagem 27
De maneira geral, a forma implícita é preferível. Nela, não é possível declarar múltiplas 
variáveis na mesma linha.
Além de variáveis, podemos declarar constantes com a palavra-chave final. Constantes não 
podem mudar de valor.
final var paginas = 100;
Uma vez declaradas, podemos utilizar variáveis para realizar operações básicas, como 
soma, subtração, comparações e concatenação. As operações básicas variam em cada tipo de dado. 
Sem perceber, já estudamos a primeira operação básica, chamada de atribuição e realizada pelo 
operador de =. Por exemplo:
1
2
3
4
5
var x = true;
var y = false;
System.out.println(x == y); //Imprime false
System.out.println(x != y); //Imprime true
É com esse operador que substituiremos o valor contido no interior das variáveis.
2.1.1 O tipo de dado booleano
O tipo de dado booleano, ou lógico, admite apenas dois valores: verdadeiro (true) ou falso 
(false). O valor padrão para variáveis desse tipo é false.
Podemos comparar se duas variáveis booleanas são iguais, pormeio dos operadores 
relacionais ==, e se são diferentes, utilizando o operador ! =. Por exemplo:
1
2
3
4
5
var x = true;
var y = false;
System.out.println(x == y); //Imprime false
System.out.println(x != y); //Imprime true
Importante: não confunda a atribuição (=) com a igualdade (==).
Além desses dois operadores relacionais, o tipo boolean admite três operadores condicionais 
(também chamados de operadores lógicos). São eles: operador E (&&), OU (||) e NÃO (!).
O operador E retorna true somente se os dois valores comparados forem verdadeiros. Já o 
operador OU retorna false apenas se os dois valores comparados forem falsos. Por fim, o operador 
NÃO inverte o valor sendo comparado. Por exemplo:
Programação orientada a objetos I28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
boolean v1 = true, v2 = true;
boolean f1 = false, f2 = false;
System.out.println("Comparação com E (&&)");
System.out.println(v1 && v2); //Imprime true, ambos verdadeiros
System.out.println(v1 && f2); //Imprime false, f2 é falso
System.out.println(f1 && v2); //Imprime false, f1 é falso
System.out.println(f1 && f2); //Imprime false, ambos falsos
System.out.println("Comparação com OU (&&)");
System.out.println(v1 || v2); //Imprime true, ambos verdadeiros
System.out.println(v1 || f2); //Imprime true, v1 é verdadeiro
System.out.println(f1 || v2); //Imprime true, v2 é verdadeiro
System.out.println(f1 || f2); //Imprime false, ambos falsos
System.out.println("Negação com !");
System.out.println(!v1); //Imprime false, pois v1 é true
System.out.println(!f1); //Imprime true, pois f1 é false
Obviamente, você poderia combinar operadores para realizar operações complexas, como:
var complexo = v1 && !(v2 || f2);
Qual seria o valor da variável complexa? Isso te obrigaria a avaliar a expressão parte a parte.
v1 && !(v2 || f2) → v2 || f2 é true
v1 && !true → !true é false
v1 && false → v1 && false é false
Portanto, o valor da variável complexa será false.
2.1.2 Tipos numéricos
Os tipos numéricos são divididos em números inteiros, sem casa decimal, e números de 
ponto flutuante. A Tabela 1 descreve os diferentes tipos inteiros, os valores máximos e mínimos 
que podem ser representados e quantos bytes ocupam na memória.
Tabela 1 – Tipos inteiros
Tipo Máximo / Mínimo Bits
byte –128 até 127 8
short –32.768 até 32.767 16
int –2.147.483.648 até 2.147.483.647 32
long –9.223.372.036.854.775.808 até 9.223.372.036.854.775.807 64
Fonte: ORACLE, 2017b.
Para os tipos de dados de ponto flutuante, temos apenas os tipos float (32 bits) e double 
(64 bits). Apesar do grande número de tipos, utilizaremos int e double na maior parte dos casos.
Conhecendo a linguagem 29
Literais numéricos
Quando os números aparecem no código sem especificarmos seus tipos, nós os chamamos 
de literais numéricos (DEITEL; DEITEL, 2010). Podemos utilizar a letra L, para especificar que um 
número deve ser encarado como long, ou a letra f, para que seja declarado como float. Em literais, 
também podemos utilizar o _, para separar dígitos. Finalmente, podemos utilizar alguns prefixos 
para alterar a base numérica em que o literal é fornecido, sendo 0x para hexadecimal, 0b para 
binário e somente 0 para a base octal. Veja alguns exemplos:
var longNum = 12L; //Essa variável é do tipo long
var intNum = 1_250; //intNum vale 1250
var doze = 0xB; //B em hexadecimal equivale a 12 em decimal
var nove = 011; //11 em octal equivale a 9 em decimal
var floatNum = .5f; //O tipo é float e o valor 0.5
var doubleNum = 1_2___5.; //O tipo é double e o valor é 125.0
Você também pode usar a letra L minúscula para o long, mas isso não é recomendado já que 
ela é muito similar ao número 1.
Type casting
Quando atribuímos o valor de um tipo de dado a outro, o Java é obrigado a fazer a conversão. 
Essa operação de conversão é chamada de type casting. Se o tipo de dado não acrescenta imprecisão, 
a conversão é automática; porém, às vezes, a operação pode resultar em perda de informação e, 
nesse caso, o Java exigirá que você indique explicitamente que a conversão deve ser feita (SIERRA; 
BATES, 2010). Como exemplo, considere o código a seguir.
1
2
3
int y = 10;
short x = y;
System.out.println(x);
Esse código apresentará erro na linha 2. Como x é uma variável inteira, ela poderia conter 
um valor muito maior ou menor do que o máximo permitido para um short.
A correção seria fazermos a operação de type casting, indicando o tipo de dado entre 
parênteses.
1
2
3
int y = 10;
short x = (short) y;
System.out.println(x);
O que aconteceria se o valor em y fosse maior do que o permitido para um short (32.767)? 
Se fosse 32.768, por exemplo? Se testarmos esse programa com o valor 32.768, obteremos como 
resultado o valor -32.768. Isso ocorre porque, ao ultrapassarmos o último valor do short, o Java 
retorna ao primeiro valor possível nesse tipo de dado, no caso -32.768, e continua somando valores, 
a partir daí, sem apresentar qualquer tipo de erro. Tenha cuidado, portanto, antes de fazer esse tipo 
de conversão.
Programação orientada a objetos I30
Operadores
Para os tipos numéricos, o Java fornece os seguintes operadores de comparação: ==, !=, >, <, 
<= e >=. Observe que o resultado de uma operação de comparação será um booleano, ou seja, um 
valor true ou false. Além disso, o Java fornece os operadores matemáticos tradicionais para soma, 
subtração, multiplicação, divisão e resto: +, -, *, / e %. Esses operadores respeitam a precedência 
matemática, ou seja, multiplicações e divisões irão ocorrer primeiro, caso sejam misturadas a 
somas e subtrações. Por exemplo:
var x = 5 + 10 * 3; //Atribui 35 a x
O sinal de menos também pode ser utilizado na frente da variável. Isso é chamado de negação 
unária, que inverte o sinal da variável. Por exemplo: no código a seguir, a variável outroNumero 
receberá o valor 12.5.
1
2
var numero = -12.5;
var outroNumero = -numero;
É possível atribuir a uma variável um valor com base em seu valor antigo, da seguinte forma:
1
2
3
var x = 10;
x = x + 5;
System.out.println(x); //Imprime 15
A operação de = será avaliada por último. Assim, na linha 2, o Java primeiro avaliará a 
expressão x + 5 com base no atual valor de x, que é 10 (linha 1). Desse modo, 10 + 5 resulta em 15. 
Somente após isso o valor de x será substituído.
Essa operação é tão comum que os operadores aritméticos podem ser combinados ao sinal 
de = para realizá-la. Por exemplo:
1
2
3
var x = 10;
x += 5; //Equivalente a x = x + 5
System.out.println(x); //Imprime 15
Além desses, para os tipos inteiros, o Java também fornece os operadores ++ e -- para somar 
ou subtrair 1 ao valor da variável. Ele pode ser usado antes ou depois da variável. Em ambos os 
casos, o valor desta será modificado, porém, se usado antes dela, o operador retornará o valor antes 
da modificação. Por exemplo:
1
2
3
4
var x = 10;
System.out.println(++x); //Muda o valor para 11 e imprime o resultado
System.out.println(x++); //Muda o valor para 12, mas imprime 11
System.out.println(x); //Imprime 12
Por fim, os tipos inteiros também fornecem operadores para manipulação de bits. A Tabela 
2, a seguir, descreve seu funcionamento considerando x os últimos 8 bits de uma variável de valor 
0010_1011.
Conhecendo a linguagem 31
Tabela 2 – Operadores para manipulação de bits
Operação Símbolo Exemplo Resultado
Right-Shift << x << 1 0101_0110
Left-Shift >> x >> 2 0000_1010
E & x & 1111_0000 0011_0000
OU | x | 1111_0000 1111_1011
OU Exclusivo ^ x ^ 1111_0000 0001_1011
Fonte: Elaborada pelo autor.
Se você achou esses operadores muito complexos, não se preocupe, eles geralmente são 
utilizados apenas em aplicações de baixo nível, como manipulação de protocolos de rede ou 
programação de firmwares.
2.1.3 O tipo char
O tipo char representa um caractere de texto. No fundo, cada caractere é representado por 
um valor numérico que varia de 0 até 65.535; portanto, ocupa 2 bytes na memória. Por causa dessa 
conversão, é possível utilizar qualqueroperador numérico em variáveis do tipo char.
Definimos um char, de maneira literal, por meio de aspas simples.
var letra = 'x';
Por utilizar a codificação Unicode para representar caracteres, o Java não tem problemas 
com acentuação, como ocorre em outras linguagens.
2.1.4 Texto
Além dos oito tipos primitivos vistos até agora, o Java também dá suporte ao texto por meio 
de variáveis do tipo String. Textos literais são definidos utilizando aspas:
var nome = "Programação"
Variáveis de texto suportam a operação de concatenação por meio dos operadores + e 
+=. A concatenação une duas Strings. Por exemplo, a linha 3 deste código imprime o texto 
"Programação OO em Java":
1
2
3
var titulo = "Programação OO";
var subtitulo = "em java";
System.out.println(titulo + subtitulo);
Podemos descobrir a quantidade de caracteres dentro de uma String por meio do comando 
length(). No caso do código anterior, subtitulo.length() resultaria no valor 7.
Por fim, podemos ler o valor de um caractere dentro do texto por meio da função charAt. 
Devemos informar a posição desse caractere, iniciando em 0. Por exemplo: titulo.charAt(3) nos 
retornaria a quarta letra, ou seja, char "g".
Programação orientada a objetos I32
2.1.5 Enumerações
Enumerações representam um conjunto fixo de valores. Imagine a seguinte situação: digamos 
que você vai trabalhar com um sistema que utilize baralho e gostaria de um tipo de dado para 
representar os naipes. Como sabemos, só existem quatro naipes possíveis: paus, ouros, espadas e 
copas. Você poderia criar para isso uma enumeração chamada Naipes. A criação de enumerações 
envolve dois passos. São eles:
1. Definir a enumeração: dar um nome para esse nosso tipo de dado e, em seguida, 
especificar quais são os seus valores possíveis.
2. Utilizar a enumeração: declarar uma variável do tipo da enumeração e atribuir a ela 
valores.
Para o caso do exemplo, iniciaríamos criando o arquivo Naipes.java e colocando nele o 
seguinte conteúdo:
1
2
3
public enum Naipes {
 Paus, Ouros, Copas, Espadas
}
Observe que até agora não criamos nenhuma variável. Estamos apenas explicando para o 
Java o que é um Naipe. Agora, podemos, em nosso main, utilizar esse novo tipo de dado:
1
2
var valor = Naipes.Paus;
System.out.println(valor); //Imprime Paus
As enumerações contêm várias operações interessantes. É possível chamar Naipes.values() 
para obtermos um vetor com todos os valores de Naipes possíveis dentro, na ordem em que foram 
declarados. Além disso, podemos obter um naipe por meio do texto, com o comando valueOf().
Mas atenção: o Java disparará um erro caso o valor não exista. Se quisermos obter o valor do enum 
em forma de texto, podemos usar a função name(). Por fim, podemos saber qual a ordem do naipe, 
iniciada em 0, utilizando a função ordinal(). Veja no exemplo a seguir.
1
2
3
4
var valor = "Ouros";
Naipes naipe = Naipes.valueOf(valor);
System.out.println(valor.ordinal()); //Imprime 1
System.out.println(valor.name()); //Imprime Ouros
As enumerações são muito mais poderosas do que isso, exploraremos vários outros recursos 
em capítulos futuros.
2.1.6 Vetores e matrizes
Muitas vezes, precisamos trabalhar com listas de valores. Para isso, o Java permite definir 
estruturas conhecidas como vetores (arrays). Elas associam um conjunto de valores a um índice 
iniciado em 0. Podemos declarar um array utilizando o operador de []. Veja alguns exemplos:
Conhecendo a linguagem 33
1
2
3
4
5
6
int[] x = new int[] {10,2,30,-5};
var y = new double[10];
char[][] z;
System.out.println(x[0]); //Imprime 10
System.out.println(x[2]); //Imprime 30
Observe, nas linhas 5 e 6, como os índices são usados. 
O que acontece com o array declarado na linha 2? Nessa linha, foi criado um array com 10 
variáveis do tipo double. Como não especificamos seus valores, o Java utilizou o valor padrão. Para 
qualquer variável numérica, o valor padrão será 0. Então, nesse caso, há um array com 0 em todas 
as suas posições.
A linha 3 é um caso diferente. Criamos uma variável chamada z, que conterá um array 
bidimensional de caracteres; porém, essa variável não foi inicializada com nenhuma lista. Ela 
ganha, então, o valor especial null. Se tentarmos imprimir um índice qualquer de z, obteremos 
uma mensagem de erro. Null é também o valor padrão de Strings, enumerações e, como veremos 
no próximo capítulo, objetos.
Similar às Strings, também é possível utilizar o comando length para descobrir o tamanho 
de um array. No exemplo anterior, x.length resultaria no valor 4.
Diferentemente de outras linguagens, o Java não exige que arrays com mais de uma dimensão 
sejam quadrados, ou seja, devemos imaginar uma lista bidimensional, como uma lista de listas, e 
não como uma matriz. Como matrizes retangulares são extremamente comuns, o Java também 
fornece uma forma direta de declaração desse tipo de estrutura. Vejamos alguns exemplos de 
declaração de matrizes.
1
2
3
4
5
6
7
8
9
10
11
12
13
var xadrez = new char[8][8];
var irregular = new int[][] {
 {1},
 {1}, {2},
 {},
 {1}, {2}, {3}, {4}, {5}
};
var irregular2 = new int[4][];
irregular2[0] = new int[1];
irregular2[1] = new int[2];
irregular2[2] = new int[0];
irregular2[3] = new int[5];
A declaração da linha 1 cria uma matriz quadrada de oito linhas e oito colunas, todas elas 
contendo caracteres. Como não informamos exatamente quais caracteres estão lá dentro, o Java os 
inicializou com o valor padrão 0.
Programação orientada a objetos I34
Na linha 2, declaramos a matriz irregular com uma lista de um único inteiro na sua 
primeira linha, dois inteiros na segunda linha, nenhum inteiro na terceira linha e cinco inteiros 
na quarta linha.
Um detalhe importante sobre o código da linha 5: ele cria um array vazio, o que é diferente 
do null que comentamos há pouco. Nesse caso, existe um vetor naquela posição, mas ela não possui 
nenhum número dentro. O null indicaria que o vetor não existe, ou seja, não poderíamos nem 
mesmo usar a função length sobre ele.
Na linha 9, declaramos uma matriz de quatro linhas, mas somente indicamos que as 
colunas seriam formadas de arrays de ints. As quatro linhas foram criadas, mas contendo null 
em seus valores.
Nas linhas seguintes, definimos quais arrays são esses, linha a linha. Sendo assim, 
estabelecemos uma matriz exatamente com as mesmas dimensões da matriz irregular, porém 
com todos os inteiros inicializados em seu valor padrão 0.
2.2 Controle de fluxo: estruturas de decisão
Muitas vezes, precisamos executar ou não um trecho de código de acordo com uma condição. 
O Java apresenta duas estruturas de decisão importantes, o if e o switch. Além disso, ele também 
fornece um operador com base em decisão: o operador ternário. Vamos estudar essas estruturas.
2.2.1 If e else
O if executa uma instrução ou bloco de código caso a condição seja verdadeira. Opcional- 
mente, podemos usar a instrução else, que será executada caso o if seja falso. Por exemplo:
1
2
3
4
5
6
7
var idade = 10;
if (idade < 18) {
 System.out.println("Menor de idade");
} else {
 System.out.println("Maior de idade");
}
Esse programa imprimirá o texto "Menor de idade". Isso porque a condição idade < 18, 
presente na linha 3, é verdadeira. Se você alterar o valor da variável idade para 18, ele passará a 
imprimir "Maior de idade", afinal, a expressão idade < 18 agora é falsa.
Como temos apenas um comando dentro do if, as chaves são opcionais, porém constitui boa 
prática utilizá-las, conforme recomendado nas convenções de código (SUN MICROSYSTEMS, 
1997). A exceção disso é quando queremos colocar outro if logo após o else para testar múltiplas 
condições, como no exemplo a seguir:
Conhecendo a linguagem 35
1
2
3
4
5
6
7
if (idade < 14) {
 System.out.println("Criança");
} else if (idade < 18){
 System.out.println("Adolescente");
} else {
 System.out.println("Adulto");
}
Operador ternário
Muitas vezes, queremos atribuir o valor de uma variável com base em uma condição. Para 
isso,podemos utilizar o operador ternário na seguinte forma:
valor = condição ? valor caso verdadeiro : valor caso falso;
Vejamos um exemplo:
var hcg = 4.0;
var resultado = hcg >= 5.0 ? "Grávida" : "Não grávida";
Então, a variável resultado receberá o valor "Não grávida". Como se trata de um operador, os 
valores dos dois lados da expressão precisam ser, obrigatoriamente, do mesmo tipo.
2.2.2 Switch
Muitas vezes, precisamos desviar o fluxo com base em um conjunto de valores. Para isso, 
utilizamos o comando switch.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var exemplo = 1;
switch (exemplo) {
 case 1:
 System.out.println("Primeira condição");
 break;
 case 2:
 System.out.println("Segunda condição");
 case 3:
 System.out.println("Terceira condição");
 break;
 default:
 System.out.println("Outra condição");
 break;
}
Programação orientada a objetos I36
Observe, na linha 2, que o comando switch utilizou como base a variável exemplo, que, nesse 
caso, é numérica. Ela também poderia ser uma String ou uma enumeração.
Em cada case, colocamos o valor esperado seguido de dois pontos (:) e o código que queremos 
executar, caso o valor da variável corresponda ao case. No exemplo, como o valor da variável é 1, o 
código imprimirá "Primeira condição".
O código dentro de cada case executa até que o break seja executado. Caso não haja um 
comando break, o código prosseguirá para dentro do próximo case. Desse modo, se alterássemos o 
valor da variável exemplo para 2, o sistema imprimiria:
Segunda condição
Terceira condição
Isso ocorre porque não há break dentro do case 2 e é chamado de fallthrough. Como você 
mesmo deve ter notado pelo exemplo, pode gerar um código confuso. Por fim, existe o bloco 
opcional default, que é executado se nenhuma das condições anteriores for atendida.
2.3 Controle de fluxo: estruturas de repetição
É frequente também a necessidade de repetir um trecho de código várias vezes. Essa operação 
é conhecida como iteração, loop ou laço. Para isso, o Java fornece quatro comandos: while, do 
while, for e for each. Que tal aprendermos sobre cada um deles?
2.3.1 Repetição com while e do while
Os comandos while e do while repetem um comando ou bloco de comandos enquanto uma 
condição for verdadeira. Observe o código a seguir.
1
2
3
4
5
6
var x = 1;
while (x <= 3) {
 System.out.print(x + ", ");
 x++;
}
System.out.println("indiozinhos");
Ele tem como resultado o seguinte texto:
1, 2, 3, indiozinhos
O do while é similar, porém a condição será testada ao final da repetição, e o código 
executará pelo menos uma vez. O código a seguir tem o mesmo resultado:
Conhecendo a linguagem 37
1
2
3
4
5
6
var x = 1;
do {
System.out.print(x + ", ");
x++;
} while (x <= 3);
System.out.println("indiozinhos");
Porém, com x = 4, o primeiro exemplo imprimiria "indiozinhos", enquanto o segundo 
exemplo imprimiria "4, indiozinhos".
2.3.2 A instrução for
A instrução for é formada por três partes:
a. Inicialização: permite a criação e inicialização de variáveis.
b. Condição: mantém o for executando enquanto for verdadeira.
c. Operação: é executada a cada iteração do for.
Para deixar mais claro, vamos reescrever o exemplo dos indiozinhos utilizando o for:
1
2
3
4
for (var x = 1; x <= 3; x++) {
 System.out.print(x + ",");
}
System.out.println("indiozinhos");
O resultado é o mesmo:
1, 2, 3, indiozinhos
O comando for é muito utilizado para imprimir os elementos de um array. Por exemplo:
1
2
3
4
5
var frutas = new String[] {"Laranja, Banana, Maçã"};
for (var i = 0; i < frutas.length; i++) {
 var fruta = frutas[i];
 System.out.println(fruta);
}
Esse programa imprime, em ordem:
Laranja
Banana
Maçã
Há outras formas de fazê-lo. Uma delas é por meio do comando for each, introduzido na 
versão 5.0 do Java. Veremos seu funcionamento a seguir.
Programação orientada a objetos I38
For each
Na verdade, iterar sobre os elementos de uma lista é uma tarefa tão comum que uma estrutura 
for foi criada inteiramente para isso. É chamado de for each, que significa "para cada" em tradução 
literal. O mesmo código anterior poderia ser reescrito assim:
1
2
3
4
var frutas = new String[] {"Laranja, Banana, Maçã"};
for (var fruta : frutas) {
 System.out.println(fruta);
}
Lemos esse for em português da seguinte forma: "para cada fruta no array de frutas". Essa 
é a melhor forma de iterar: não só melhora a leitura, como é mais eficiente em coleções mais 
avançadas (BLOCH, 2019).
O Capítulo 7, que trata da biblioteca de coleções do Java, mostrará outras formas de percorrer 
listas de objetos.
2.3.3 Interrompendo laços com break e continue
Muitas vezes, precisamos interromper um laço de um loop ou mesmo a iteração inteira, 
dependendo de alguma condição. Para isso, o Java disponibiliza dois comandos:
• Continue: que interrompe imediatamente aquela iteração, fazendo com que a condição 
do laço seja novamente testada.
• Break: que interrompe completamente o laço.
Digamos que nós temos uma lista com números e queremos imprimir somente os números 
pares, na ordem em que aparecem. Poderíamos escrever esse laço assim:
1
2
3
4
5
6
7
8
var numeros = new int[] {10,2,23,11,14,17,6,13};
for (var numero : numeros) {
 //Se o número é impar
 if (numero % 2 == 1) {
 continue; //Pule para o próximo número
 }
 System.out.println(numero);
}
Esse programa imprime:
10
2
14
6
iterar: acessar cada 
um dos elementos 
de um vetor em 
ordem.
Conhecendo a linguagem 39
Caso haja um laço dentro do outro, esses comandos atuarão no mais interno, mas é possível 
também incluir marcadores (labels), caso você precise abandonar os mais distantes. O código a 
seguir imprime os números linha a linha, mas interrompe o laço imediatamente caso o número 0 
seja encontrado.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var matrizQuadrada = new int[][] {
 {1,2,3,4,5},
 {10,20,30,0,40},
 {100, 200, 300, 400, 500}
};
externo:
for (int i = 0; i < matrizQuadrada.length; i++) {
 System.out.println();
 for (var numero : matrizQuadrada[i]) {
 System.out.print(numero + " ");
 if (numero == 0) {
 break externo;
 }
 }
} 
O resultado será:
1 2 3 4 5
10 20 30 0
Observe o marcador externo na linha 7, que atua sobre o for da linha seguinte. É ele que faz 
com que o break colocado na linha 13 interrompa completamente os dois laços, em vez de somente 
o laço interno.
Caso tenha três ou mais comandos for, você poderá usar mais de um marcador, entretanto, 
uma boa estruturação de código fará com que o uso de labels seja muito raro.
2.4 Escopo de variáveis
Observe que todos os programas que vimos até aqui utilizaram as chaves para criar blocos 
de código. É importante saber que as variáveis só existem a partir da linha em que forem declaradas 
e no interior de blocos em que foram criadas (SIERRA; BATES, 2010).
No caso de um bloco estar dentro do outro, ele conseguirá utilizar variáveis do bloco em que 
está contido. Por exemplo, no código a seguir:
Programação orientada a objetos I40
1
2
3
4
5
6
7
var x = 10;
for (var i = 0; i < 10; i++) {
 var a = i*2;
 System.out.println(a);
 System.out.println(x);
}
System.out.println(a); //ERRO
A variável x pode ser utilizada na linha 5, pois está dentro do bloco da função main, assim 
como o for. Observe que a variável a foi declarada na linha 3, no interior do bloco do for, portanto 
não pode mais ser usada na linha 7. Como seu bloco deixou de existir, a variável também deixou de 
existir. O bloco definido nas chaves das linhas 2 e 7 definem o escopo da variável. E a variável i? No 
caso do comando for, o escopo dela é o mesmo da variável a. É uma boa prática manter as variáveis 
no menor escopo possível (DEITEL; DEITEL, 2010).
Tenha sempre em mente que boas práticas, como restringir o escopo da variável, evitam que 
você mesmo cometa erros, simplificando a programação.
Ampliando seus conhecimentos
• ORACLE. Lesson: language basics. The Java Tutorials, 2019. Disponívelem: https://docs.
oracle.com/javase/tutorial/java/nutsandbolts/index.html. Acesso em: 24 set. 2019.
Caso você domine o inglês, é sempre importante consultar a documentação oficial da 
Oracle. Nela, você encontrará tutoriais e a descrição detalhada de todos os elementos da 
linguagem.
• SIERRA, K.; BATES, B. Use a cabeça! Java. Rio de Janeiro: Alta Books, 2010.
O livro de Kathy Sierra e Bert Bates apresenta a linguagem de maneira bastante 
extrovertida e, por isso, é uma boa referência.
• CURSO de Java 63: printf, 2016. 1 vídeo (21 min). Publicado pelo canal Loiane Groner. 
Disponível em: https://www.youtube.com/watch?v=3Ie7VMJWoYo. Acesso em: 24 set. 
2019.
O comando printf é uma poderosa forma de imprimir dados. Para saber mais sobre isso, 
recomendamos a videoaula 63 do curso de Java, de Loiane Groner.
• CURSO de Java 12: lendo dados do teclado usando a classe Scanner, 2015. 1 vídeo (22 
min). Publicado pelo canal Loiane Groner. Disponível em: https://www.youtube.com/
watch?v=Z6Y8zupCKfk. Acesso em: 24 set. 2019.
Ler dados do teclado também é muito importante. Para saber mais sobre o assunto, assista 
à videoaula 12, de Loiane Groner.
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/index.html
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/index.html
https://www.youtube.com/watch?v=3Ie7VMJWoYo
https://www.youtube.com/watch?v=Z6Y8zupCKfk
https://www.youtube.com/watch?v=Z6Y8zupCKfk
Conhecendo a linguagem 41
Atividades
1. Escreva dois programas para imprimir todos os números pares de 2 até 20. O primeiro deve 
usar o comando while e o segundo, o comando for. Não utilize o comando continue.
2. O que o programa a seguir imprime? Você pode executar o código mentalmente ou com a 
ajuda de um papel.
1
2
3
4
5
var letras = new char[]{'a','b','e','j','m','o','u','v','z',' '};
var idx = new int[]{2, 6, 9, 0, 4, 5, 9, 5, 9, 3, 0, 7, 0};
for (var i : idx) {
 System.out.print(letras[i]);
}
3. Identifique os tipos declarados a seguir.
var a = "a";
var b = 10L;
var c = -.2;
var d = 0f;
Referências
BLOCH, J. Java Efetivo: as melhores práticas para a plataforma Java. Trad. de C. R. M. Ravaglia. 3. ed. Rio de 
Janeiro: Alta Books, 2019. 
DEITEL, H. M.; DEITEL, P. Java: como programar. 8. ed. Trad. de E. Furmankiewicz. São Paulo: Pearson, 
2010.
ORACLE. Primitive Data Types. The Java Tutorials, 2017a. Disponível em: https://docs.oracle.com/javase/
tutorial/java/nutsandbolts/datatypes.html. Acesso em: 24 set. 2019.
ORACLE. Learning the Java Language. The Java Tutorials, 2017b. Disponível em: https://docs.oracle.com/
javase/tutorial/java/TOC.html. Acesso em: 24 set. 2019.
SIERRA, K.; BATES, B. Use a cabeça, Java! Trad. de A. J. Coelho. Rio de Janeiro: Alta Books, 2010.
SUN MICROSYSTEMS. Java Code Conventions. Oracle Technetwork, 12 set. 1997. Disponível em: https://
www.oracle.com/technetwork/java/codeconventions-150003.pdf. Acesso em: 24 set. 2019.
3
Classes e objetos
Problemas são complexos. Pare para pensar alguns segundos em quantos detalhes estão 
envolvidos na resolução do problema de transportar pessoas: segurança, cobrança, o melhor 
caminho de um ponto ao outro (mesmo em meio ao trânsito) etc. A tecnologia vem como aliada 
das empresas nesse ponto, e, dando suporte a tudo, está o software, portanto, não é surpresa que 
ele seja igualmente complexo.
Felizmente, as linguagens de programação fornecem estruturas cada vez mais refinadas 
para decompor o problema em partes menores. Neste capítulo, iniciaremos o estudo de um dos 
principais paradigmas modernos que nos auxiliam nessa tarefa: a orientação a objetos. Aqui você 
começará a desvendar esse mundo, entendendo o que são classes e objetos e como podemos utilizar 
a linguagem para modelá-los.
3.1 Classes e objetos no mundo real
Desde criança, procuramos entender os objetos do mundo real. Quando os analisamos, 
prestamos atenção em cada um dos seus atributos, como sua cor, forma, altura e peso.
Figura 1 – Cor, tamanho, forma são atributos dos objetos
al
ta
na
ka
/S
hu
tt
er
st
oc
k
Além dos atributos, também procuramos conhecer o conjunto de operações que os objetos 
podem realizar. Por exemplo, pássaros e insetos são capazes de voar, um carro pode transportar 
pessoas, um cachorro late etc.
Programação orientada a objetos I44
Figura 2 – A operação de um instrumento é fazer som
m
ax
im
 ib
ra
gi
m
ov
/S
hu
tt
er
st
oc
k
 Ao entendermos os objetos a nossa volta, os classificamos em diferentes tipos. Por exemplo, na 
Figura 2, sabemos que a criança está com uma guitarra em mãos. O conceito da guitarra foi percebido 
pela forma do instrumento, por sabermos que possui cordas, e pela maneira como ela está tocando.
Repare que, embora estejamos olhando para um único objeto concreto – isto é, aquela 
guitarra, daquela menina – para nós, o conceito de guitarra engloba uma série de objetos similares 
que podem variar em sua cor, tamanho e formato, mas que terão um conjunto de atributos e 
operações em comum, como representado pela Figura 3.
Figura 3 – Guitarra: objetos diferentes, um só conceito
Ch
ris
to
ph
er
 H
al
l/
Sh
ut
te
rs
to
ck
Classes e objetos 45
A este conceito damos o nome de abstração, que é definido por Booch et al. (2006, p. 44) 
como "as características essenciais de um objeto que os distinguem de todos os outros tipos de 
objetos e, por consequência, fornecem fronteiras rígidas e bem definidas, relativas à perspectiva 
do observador".
Vemos aqui dois conceitos distintos, mas correlacionados. O primeiro é o conceito de objeto, 
também chamado de instância, que se refere a um objeto específico. O outro é o conceito de classe, 
que se refere ao tipo desse objeto e, com base nele, sabemos que atributos e operações deveriam 
estar presentes em cada uma de suas instâncias.
Como já mencionamos em outras ocasiões, o Java é uma linguagem orientada a objetos. 
O que isso significa? Significa que a linguagem nos dará mecanismos para definir e criar nossas 
próprias classes e, com base nelas, gerar os objetos que compõem os dados de nossos programas. 
Programar em uma linguagem orientada a objetos envolve focar os esforços não tanto nos 
algoritmos, mas em criar em software boas abstrações dos objetos do mundo real e, então, 
modelar suas interações.
Esta estratégia nos permite lidar com a complexidade do software por meio da decomposição 
dos vários problemas complexos em problemas menores. Na prática, cada classe se transformará 
em um pequeno programa, com funções e dados bem isolados e definidos. O software como um 
todo terá centenas ou milhares de classes cooperando entre si.
3.2 Sua primeira classe
Em Java, definimos uma nova classe por meio da palavra-chave class. Uma classe definirá um 
novo tipo de dado. Além disso, cada classe em Java será geralmente definida em seu próprio arquivo.
Por exemplo, vamos supor que estejamos programando um sistema astronômico e gostaríamos 
de descrever os planetas. Sabemos que os planetas, no mundo real, têm milhares de atributos: nome, 
massa, diâmetro, vegetação, composição mineral, densidade, distância até o Sol, entre outros, mas 
iremos incluir no sistema somente aqueles que nos interessam. Em nosso caso, poderia ser um texto 
com o nome, a massa (medida em "Terras") e o diâmetro (medido em quilômetros).
Para isso, crie um novo projeto, vá até a pasta src, clique no botão direito e selecione New e 
Java Class. Dê o nome para essa classe de Planeta e clique em OK. Observe que o IntelliJ criou um 
arquivo chamado Planeta.java e, dentro dele, colocou o seguinte código:
1
2
public class Planeta {
}
Nele, as palavras-chave public class indicam ao Java que uma nova classe será criada. Em 
seguida, escrevemos o seu nome: Planeta.
Já definimos que os atributos da nossa classe são três: nome, massa e diâmetro. 
Representaremos isso em Java, indicando que a classe Planeta possui internamente três variáveis, 
que devem ser declaradas da maneira explícita:
Programação orientada a objetos I46
1
2
3
4
5
publicclass Planeta {
 String nome = "";
 int diametro;
 double massa;
}
Observe que, até agora, nós apenas descrevemos para Java o que é um planeta, ou seja, nós 
modelamos um conceito, uma abstração, na forma de um tipo de dado que chamamos de Planeta. 
Agora, gostaríamos de criar, em nosso programa, alguns planetas específicos. Por exemplo, 
podemos descrever os planetas Mercúrio, Terra e Saturno. Estes são nossos objetos, ou seja, 
instâncias (exemplos) de nossa classe.
Vamos fazer isso em um novo arquivo. Clique novamente na pasta src e crie uma nova classe 
chamada Main. Nele, inclua a função main. Ao final, seu projeto deve se parecer com isso:
Figura 4 – Projeto com duas classes no IntelliJ
Fonte: Elaborada pelo autor.
Criaremos objetos utilizando a palavra-chave new, da seguinte forma:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var planeta1 = new Planeta();
planeta1.nome = "Mercurio";
planeta1.diametro = 4_878;
planeta1.massa = 0.055;
var planeta2 = new Planeta();
planeta2.nome = "Terra";
planeta2.diametro = 12_742;
planeta2.massa = 1.0;
var planeta3 = new Planeta();
planeta3.nome = "Saturno";
planeta3.diametro = 120_536;
planeta3.massa = 95.2;
Classes e objetos 47
Observe que criamos três variáveis chamadas planeta1, planeta2 e planeta3. Essas variáveis 
têm como tipo de dado a nossa classe Planeta. Além disso, perceba que elas se referem a três objetos 
diferentes, os planetas Mercúrio, Terra e Saturno.
Como o Java é uma linguagem fortemente tipada, ele garantirá que variáveis de classes 
diferentes não se misturem. Por exemplo, se colocássemos no método main o seguinte código e 
tentássemos compilar o programa:
1
2
3
4
5
6
7
public class Main {
 public static void main(String[] args) {
 var planeta = new Planeta();
 var cachorro = new Cachorro();
 planeta = cachorro;
 }
}
Receberíamos do compilador a seguinte mensagem de erro:
Error:(5, 19) java: incompatible types: Cachorro cannot be converted to Planeta
Isso significa que Cachorro e Planeta são coisas diferentes e não podemos misturá-los.
3.2.1 Métodos
Além de atributos, também podemos definir operações que os planetas podem realizar 
no contexto do nosso sistema. A primeira operação que podemos inserir para nosso planeta é a 
obtenção do raio. Como sabemos, o raio equivale à metade do diâmetro. Fazemos isso definindo 
uma função no interior do objeto, chamada de método.
A declaração de função segue a seguinte sintaxe (DEITEL; DEITEL, 2010):
tipo nomeDaFunção(tipo parametro1, tipo parametro2) {
 código
 return valor;
}
O tipo de retorno, nome do método e parâmetros de retorno definem o que chamamos de 
assinatura do método. Observe que o método também define um bloco de código, dentro da classe, 
portanto, elas podem utilizar os valores dos atributos da classe e, ao mesmo tempo, podem conter 
novas variáveis restritas ao seu interior, chamadas de variáveis locais.
Programação orientada a objetos I48
Voltemos ao exemplo do método do raio. Ele seria implementado da seguinte forma:
1
2
3
4
5
6
7
8
9
public class Planeta {
 String nome = "";
 int diametro;
 double massa;
 double raio() {
 return diametro / 2.0;
 }
}
Note que o tipo de retorno dele é um double, já que é o tipo de dado do raio calculado. A 
palavra-chave return indica qual valor será o resultado da execução desse método. É importante 
saber que o método será imediatamente interrompido quando ela for atingida. Podemos usar esse 
método em nosso main, da seguinte forma:
1
2
3
4
5
6
7
var planeta1 = new Planeta();
planeta1.nome = "Mercurio";
planeta1.diametro = 4_878;
planeta1.massa = 0.055;
System.out.println(planeta1.nome);
System.out.println(planeta1.raio());
Esse código imprimirá:
Mercurio
2439.0
Como declararíamos o tipo de retorno de um método que, por exemplo, fizesse só impressão 
de dados sem retornar qualquer tipo de valor? Bastaria declarar o método com o tipo de dado void 
(vazio). Nesse caso, a palavra return não é mais obrigatória, mas pode ser usada para interromper o 
método. Por exemplo, poderíamos programar o método imprimir na classe Planeta assim:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Planeta {
 String nome = "";
 int diametro;
 double massa;
 double raio() {
 return diametro / 2.0;
 }
 void imprimir() {
 System.out.println("Nome: " + nome);
 System.out.println("Diâmetro: " + diametro);
 System.out.println("Massa: " + massa);
 }
}
Classes e objetos 49
Obviamente, um método pode executar outro. Por exemplo, vamos supor que também 
quiséssemos calcular a área da superfície do planeta. Matematicamente, a área da superfície de 
uma esfera é definida por 4πr2. Poderíamos implementar o método areaSuperficie() assim:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Planeta {
 String nome = "";
 int diametro;
 double massa;
 double raio() {
 return diametro / 2.0;
 }
 double areaSuperficie() {
 var raioAoQuadrado = raio() * raio();
 return 4 * 3.1415 * raioAoQuadrado;
 }
 void imprimir() {
 System.out.println("Nome: " + nome);
 System.out.println("Diâmetro: " + diametro);
 System.out.println("Massa: " + massa);
 System.out.println("Raio: " + raio());
 System.out.println("Area da superfície:" + areaSuperficie());
 }
}
Observe, na linha 11, que o método areaSuperficie() define a variável local raioAoQuadrado 
e utiliza a função raio() duas vezes. Também atualizamos nossa função imprimir() para incluir os 
dados calculados.
Quando planejamos métodos, é importante pensar com cuidado em sua assinatura (BLOCH, 
2019). Bons nomes podem melhorar muito a legibilidade do código, simplificando sua manutenção.
3.2.2 Construtores
Quando utilizamos a palavra-chave new para criar um novo objeto, estamos utilizando uma 
função especial chamada construtor (SIERRA; BATES, 2010). Seu objetivo é inicializar o valor dos 
atributos da classe quando uma nova instância for gerada.
Caso não criemos um construtor, o Java o criará automaticamente. Nesse caso, os atributos 
serão inicializados com o valor padrão (0 para números, false para booleanos e null para objetos), 
ou com os valores já indicados na declaração (como o valor de um texto vazio que utilizamos no 
nome, indicado pelas aspas). Entretanto, podemos criar nossos próprios construtores e, inclusive, 
passar para eles parâmetros. Vamos adicionar um construtor à classe Planeta para que possamos 
informar o valor dos seus atributos diretamente. O construtor é declarado como na forma de uma 
função com o próprio nome da classe e sem tipo de retorno, por exemplo:
Programação orientada a objetos I50
1
2
3
4
5
6
7
8
9
10
public class Planeta {
String nome;
int diametro;
double massa;
public Planeta(String n, int d, double m) {
nome = n;
diametro = d;
massa = m;
}
Observe que nosso construtor, definido na linha 6, contém três parâmetros que chamamos 
de n, d e m. Usamos o valor desses parâmetros para inicializar o nome, diâmetro e massa do 
Planeta. Se tentarmos executar nosso código agora, obteremos o seguinte erro:
Main.java
Error:(3, 24) java: constructor Planeta in class Planeta cannot be applied to given 
types;
required: java.lang.String,int,double
found: no arguments
reason: actual and formal argument lists differ in length
O que esse erro quer dizer? Significa que na linha 3 do arquivo Main.java estamos usando um 
construtor sem parâmetros na classe Planeta, mas ele não existe. Isso ocorre porque, ao declararmos 
nosso construtor, o Java não nos fornecerá mais o construtor padrão automaticamente. Podemos 
corrigir a função no main utilizando nosso construtor:
1
2
3
4
5
6
var planeta1 = new Planeta("Mercurio", 4_878, 0.055);
planeta1.imprimir();
var planeta2 = new Planeta("Terra", 12_742, 1.0);
var planeta3 = new Planeta("Saturno", 120_536, 95.2);
Uma prática comum em construtores é declarar o nome dos parâmetros exatamente iguais 
ao nome dos atributos, porém, com o conhecimentoque temos até agora, isso geraria um código 
ambíguo, observe:
1
2
3
4
5
Planeta(String nome, int diametro, double massa) {
 nome = nome;
 diametro = diametro;
 massa = massa;
}
Na linha 2, gostaríamos que a palavra nome, do lado esquerdo do sinal de igual, se referisse ao 
atributo nome do objeto; e a palavra nome, do lado direito, se referisse ao parâmetro nome, declarado 
Classes e objetos 51
na assinatura do método (antigamente chamado de n). Como resolver esse impasse? Para isso, o 
Java define a palavra-chave this. Ela significa "o próprio objeto" e, por meio dela, referenciamos o 
atributo, não o parâmetro do método. Assim, o código final do nosso construtor será:
1
2
3
4
5
Planeta(String nome, int diametro, double massa) {
 this.nome = nome;
 this.diametro = diametro;
 this.massa = massa;
}
E se quiséssemos que o construtor sem parâmetros ainda existisse? Nesse caso, bastaria 
declararmos um segundo construtor sem parâmetros e inicializar nele as variáveis:
1
2
3
4
5
Planeta() {
 this.nome = "";
 this.diametro = 0;
 this.massa = 0;
}
Há uma forma ainda mais fácil de fazer isso. A palavra-chave this pode ser utilizada na 
primeira linha de um construtor como uma referência a outro construtor. Desse modo, poderíamos 
reescrever esse construtor chamando nosso construtor de três parâmetros:
1
2
3
Planeta() {
 this("", 0, 0.0);
}
Não há limites para o número de construtores que podemos criar. Observe que, na ausência 
de um construtor padrão, podemos utilizar construtores para obrigar o usuário a informar 
determinados atributos.
3.3 A palavra-chave static
Às vezes, precisamos criar um método ou atributo que se refere à classe como um todo, e não 
a determinada instância. Damos a isso o nome de atributo ou método estático (DEITEL; DEITEL, 
2010). A diferença deles é que não precisarão da palavra-chave new para funcionar. Além disso, o 
valor de um atributo estático é compartilhado por todos os objetos da classe (SIERRA; BATES, 2010).
Definimos um atributo ou método como estático com a palavra-chave static no momento 
de sua declaração. Por exemplo, vamos definir o método estático para a descrição para a classe 
Planeta, que descreve o que um planeta é:
1
2
3
static String descricao() {
 return "Um corpo celeste esférico que orbita uma estrela";
}
Podemos utilizar esse método na função main por meio do comando:
System.out.println(Planeta.descricao());
Programação orientada a objetos I52
Essa chamada também seria possível por meio de uma variável do tipo Planeta, por exemplo:
1
2
3
4
var planeta1 = new Planeta("Mercurio", 4_878, 0.055);
//Valido, porém, confuso
System.out.println(planeta1.descricao());
Observe que, nesse código, a função descrição aparenta não ser estática e, portanto, é uma 
má prática por levar a esse entendimento errôneo.
Um dos grandes usos de atributos estáticos é a definição de constantes. Por exemplo, 
poderíamos definir a constante PI com:
final static double PI = 3.1415;
Dessa forma, a versão final da nossa classe Planeta seria:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class Planeta {
 final static double PI = 3.1415;
 String nome;
 int diametro;
 double massa;
 static String descricao() {
 return "Um corpo celeste esférico que orbita uma estrela";
 }
 Planeta(String nome, int diametro, double massa) {
 this.nome = nome;
 this.diametro = diametro;
 this.massa = massa;
 }
 Planeta() {
 this("", 0, 0.0);
 }
 double raio() {
 return diametro / 2.0;
 }
 double areaSuperficie() {
 var raioAoQuadrado = raio() * raio();
 return 4 * PI * raioAoQuadrado;
 }
 void imprimir() {
 System.out.println("Nome: " + nome);
 System.out.println("Diâmetro: " + diametro);
 System.out.println("Massa: " + massa);
 System.out.println("Raio: " + raio());
 System.out.println("Area da superfície:" + areaSuperficie());
 }
}
Classes e objetos 53
Como atributos e métodos estáticos pertencem à classe, não a uma instância específica, será 
impossível acessar métodos e atributos não estáticos da mesma classe com base neles sem que 
criemos pelo menos um objeto.
Muitos iniciantes em programação acabam criando somente atributos e métodos estáticos 
ao perceber que não conseguem acessar atributos e métodos sem esse marcador com base no 
método main. Esta não é uma prática correta e, para piorar, provavelmente será sugerida como 
correção por sua IDE.
Caso você precise acessar métodos da classe em que o main está, prefira criar um objeto, 
como no exemplo:
1
2
3
4
5
6
7
8
9
10
public class Main {
 void exemplo() {
 System.out.println("Chamando método não estático");
}
 public static void main(String[] args) {
 var main = new Main(); //Crie um objeto
 main.exemplo(); //Chame o método não estático
 }
}
Se a linha 8 contivesse somente a chamada exemplo() em vez de main.exemplo(), você receberia 
o erro Non-static method 'exemplo()' cannot be referenced from a static context, que pode ser 
traduzido como "o método não estático exemplo não pode ser acessado de um contexto estático".
Por fim, uma prática comum é criar um método não estático cujo único papel é substituir o 
main e chamá-lo por meio de um objeto anônimo:
1
2
3
4
5
6
7
8
9
public class Main {
 void run() {
 //Esse método substituirá o main
 }
 public static void main(String[] args) {
 new Main().run(); //Cria o objeto e já chama run()
 }
}
Lembre-se sempre de que métodos e atributos estáticos são exceção, não regra. Desconfie de 
sua IDE caso ela esteja sugerindo para marcar todos os lugares dessa forma.
Programação orientada a objetos I54
3.4. O valor especial null
Podemos utilizar o valor especial null para indicar que uma variável não contém 
nenhum objeto associado. Se tentarmos utilizar qualquer atributo ou método de uma variável 
nula, obteremos um erro conhecido como NullPointerException. O código a seguir simula 
essa condição:
1
2
Planeta terra = null;
System.out.println(terra.raio());
Se tentarmos executá-lo, receberemos um erro como este:
Exception in thread "main" java.lang.NullPointerException
at Main.main(Main.java:5)
Observe que ele indica que o tipo do erro é NullPointerException, ou seja, tentamos fazer 
acesso a uma variável nula. Após o at, o Java indicará a classe e o método em que o problema 
ocorreu, seguido do nome do arquivo: linha entre parênteses. Nesse caso, o erro ocorreu na classe 
Main, no método main, que está no arquivo Main.java linha 5. O valor null é o valor padrão para 
variáveis que guardam objetos.
Não confunda o null com objetos que admitem valores vazios. Por 
exemplo, é possível existir um objeto de texto sem nenhum caractere "" 
ou mesmo um array com 0 elementos.
Quando estudamos as variáveis no capítulo 2, vimos três tipos de dados que também podiam 
possuir valor null: Strings, arrays e enums. Isso porque o Java também considera esses três tipos 
como casos especiais de classes.
Isso significa que as variáveis que representam esses tipos também são referências, o que 
não é um problema para Strings ou enums, já que os valores dos objetos dessas classes, uma vez 
construídos, não podem ser modificados, mas tome cuidado no caso dos arrays. Passar um array 
por parâmetro não criará uma cópia de seus dados.
Quando você estiver começando a programar, provavelmente receberá muitas vezes o erro 
NullPointerException, descrito acima. Quando isso ocorrer, não se assuste. Basta localizar a linha 
do erro e verificar qual variável nunca foi inicializada com new. e, assim, você encontrará a falha 
em seu código.
Classes e objetos 55
Considerações finais
A capacidade humana de classificar objetos e criar abstrações é realmente impressionante. 
Quando lemos uma fase simples como "Fui de carro para a escola", não percebemos que as palavras 
carro e escola representam abstrações para qualquer carro e qualquer escola.
Uma linguagem orientada a objetos, como o Java, permite-nos criar abstrações

Outros materiais