Você está na página 1de 13

Conceitos Básicos

Blocos de Código

Em Java, tal como em C/C++, duas ou mais linhas podem ser agrupadas
formando blocos de código. Isso é feito inserindo-se os comandos entre as chaves
{ e }. Depois que um bloco de código é criado, ele se torna uma unidade lógica
que pode ser usada como se fosse um comando único. Por exemplo, um bloco
pode ser o alvo dos comandos if e for de Java. Consideremos o seguinte comando
if:

I f (a<b)
{ // Começo do bloco.
a=b;
b=0;
} // Fim de bloco.

Aqui, se a for menor do que b, as duas linhas contidas dentro do bloco


serão executadas. Assim, os dois comandos, que ficam dentro do bloco de código,
formam uma unidade lógica, e um comando não pode executado sem que o outro
também seja. O importante é saber que quisemos unir logicamente dois ou mais
comandos, fazemos isso criando um bloco.

Vejamos outro exemplo. O seguinte programa utiliza um bloco de código


como alvo para o loop for.

A saída gerada por este programa é mostrada aqui:

Valor de a: 0
Valor de b: 10
Valor de a: 1
Valor de b: 8
Valor de a: 2
Valor de b: 6
Valor de a: 3
Valor de b: 4
Valor de a: 4
Valor de a: 2

Neste exemplo, o alvo do loop for é um bloco de código e não apenas uma
só linha. Assim, cada vez que o loop for executado, os três comandos que ficam
dentro do bloco de código serão executados. Esse fato pode ser constatado na
saída gerada pelo programa.
Os programas fonte Java são formados por espaço em branco,
identificadores, comentários, literais, operadores, separadores e palavra-chave.
Os operadores serão descritos com detalhes mais adiante neste curso. Os outros
elementos são descritos a seguir.

Java é uma linguagem de forma livre. Isso significa que não é preciso
seguir regras especiais de indentação. Por exemplo, nada impede que um
programa seja escrito em uma única linha, ou de qualquer outra forma estranha
que o programador queira desde que haja pelo menos um caractere de espaço
entre cada dois elementos significativos que já não sejam delimitados por um
operador ou separador. Em Java, espaço em branco pode ser um espaço, um
caractere de tabulação ou uma quebra de linha.

Identificadores

Identificadores são palavras usadas como nomes de classes, nomes de


métodos e nomes de variáveis. Um identificador pode ser qualquer seqüência
descritiva de letra maiúsculas ou minúsculas, números, mais os caracteres de
underscore( _ ) e o cifrão ($). Um identificador não pode começar com um número,
para evitar ser confundido com um valor literal numérico.
Como já dissemos, Java faz distinção entre letras maiúsculas e minúsculas,
de modo que VALOR é um identificador diferente de Valor. Alguns exemplos de
identificadores válidos são:

TempMed
Count
Yl // Só não pode começar com um algarismo.
$tudoBem // Pode começar com $.
Isso-funciona // Pode usar o caractere de underscore.

Alguns contra-exemplos de nomes inválidos são:

2y / / Erro ! ! ! Começa com algarismo.


Temp-med / / Erro ! ! ! Utiliza o caractere -.
Não / pode / / Erro ! ! ! Usa a barra /

Valores Literais

Um valor constante em Java é criado usando-se uma representação literal


desse valor. Eis alguns exemplos de valores literais:

500 / / Um valor inteiro.


3.14 / / Valor de ponto flutuante.
“Y“ / / Constante de caractere.
“String de teste” / / Constante de string.
Um valor literal poderá ser usado em qualquer lugar no qual um valor de
seu tipo seja permitido.

Separadores

Java define alguns caracteres como separadores. O mais comum deles é o


caractere de ponto-e-vírgula (;). Outros separadores são comentados a seguir:
i.
( ) Parênteses → Usados para conter listas de parâmetros nas definições
e invocações de métodos. Também são utilizados para definir precedência de
expressões, conter expressões em comandos de controle e envolver tipos em
conversões (casts).

{ } Chaves → Usadas para conter arrays inicializados automaticamente.


Também utilizadas para definir blocos de código, em classes, métodos e escopos
locais.

[ ] Colchetes → Usados para declarar tipos de arrays. Usados também


para diferenciar valores de arrays.

; Ponto-e-vírgula → Encerra os comandos.

, Vírgula → Separa identificadores consecutivos em declarações de


variáveis. Usada também para encadear as declarações dentro de um comando
for.

. Ponto → Usado para separar nomes de packages de subpackages e


classes. Utilizado também para separar uma variável ou método de uma
referência a variável.

Palavras-chave

Existem certas seqüências de caracteres que possuem um significado


especial no Java; essas seqüências são chamadas de palavras-chave. Algumas
delas são verbos, algumas como adjetivos e outras como pronomes. Algumas
delas são tokens (termos de linguagem-fonte para computadores) guardadas para
versões posteriores da linguagem, e um (goto) é uma blasfêmia de linguagens
procedurais antigas que jamais pode ser proferido em um Java de bom gosto.

A seguir é apresentada uma lista de 56 palavras-chave que podem ser


usadas em Java. Quando você souber o significado de todos esses termos, estará
bem encaminhado para se tornar um programador em Java. As palavras-chave
não podem ser usadas como nomes de variáveis, classes ou métodos.

As palavras-chave cast, const, future, generic, goto, inner, operator,


outer, rest var são reservadas, mas não têm significado em Java. Os
programadores experientes em outras linguagens como C,C++, Pascal ou SQL,
devem saber que esses termos podem eventualmente ser utilizados. Por ora, você
não os usará, e o Java é muito mais simples e fácil de manter sem eles.

Abstract boolean break byte


case cast catch char
class const continue default
do double else extends
final finally float for
future generic goto If
implemensts impor inner instanceof
int interface long native
new null operator outer
package private protected public
rest return short static
super switch sychronized this
trhow throws Transient try
var void Volatile while

Além das palavras-chave, Java reserva as seguintes:

true, false, null

Elas representam valores definidos por Java e não podem ser usadas como
nomes de variáveis, classes ou métodos.

Biblioteca de Classes Java

O ambiente Java utiliza diversas classes de bibliotecas que contêm muitos


métodos embutidos, proporcionando suporte para operações com I/O,
manipulação de strings, recursos de rede e gráficos. As classes-padrão fornecem
também suporte para saída em janelas. Assim, Java como um todo é uma
combinação da própria linguagem, mais as classes-padrão. Veremos que grande
parte da funcionalidade de Java é acessível por meio de sua biblioteca de classes.
Na verdade, para se tornar programador em Java é preciso aprender a linguagem
e conhecer a biblioteca de classes-padrão de Java.

Tipos Simples
Como acontece com todas as linguagens de programação modernas, Java
suporta diversos tipos de dados. Podemos usar esses tipos para declarar variáveis
e criar arrays.

Desde já, é importante ter em mente que Java é uma linguagem com
tipagem forte. Na verdade, parte da robustez e da segurança de Java é
conseqüência deste fato

Mas o que significa isso?

Primeiro, toda variável em Java tem um tipo. O mesmo vale para as


expressões. Esses tipos são rigorosamente definidos.

Segundo, todas as atribuições, quer sejam explícitas ou via passagem de


parâmetros nas chamadas a métodos, são checadas quanto à compatibilidade de
tipos. Não existem conversões automáticas, nem conversões de tipos conflitantes,
como acontece em algumas linguagens. O compilador Java checa todas as
expressões e parâmetros para assegurar-se de que os tipos sejam compatíveis.
Qualquer disparidade entre tipos é um erro e deve ser corrigida para que o
compilador possa concluir a compilação da classe.

Quem tem vivência em C ou C++ perceberá que a tipagem em Java é mais


rigorosa do que nessas duas linguagens. Por exemplo, em C/C++ é possível
atribuir um valor de ponto flutuante a um inteiro. Em Java, isso não é permitido.
Também em C, não existe necessariamente checagem forte de tipos entre um
parâmetro e um argumento. Em Java, isso sempre acontece. A forte checagem de
tipos de Java pode parecer inicialmente um pouco aborrecida. Mas é preciso ter
em mente que em longo prazo isso ajudará a reduzir a possibilidade de erros no
código.

Java define oito tipos simples (ou elementares) de dados. Eles podem ser
divididos em quatro grupos (conforme tabela da página seguinte):

Esses tipos podem ser usados no estado original, ou para construir arrays
ou criar novos tipos de classes. Assim, eles formam a base de todos os outros
tipos de dados que possam ser criados.

Números Números Letras, Símbolos Valor Verdadeiro


Inteiros: Fracionários e Algarismos ou Falso
Todos com Sinal
byte float char boolean
int double
short
long

Os tipos elementares representam valores individuais, e não objetos


complexos. Embora sob outros aspectos Java seja uma linguagem totalmente
orientada para objetos, os tipos elementares não são objetos. Eles são análogos
aos tipos simples encontrados na maioria das outras linguagens não orientadas
para objetos. A razão para isso é a eficiência. Se os tipos simples fossem, objetos,
o desempenho seria muito prejudicado.

Os tipos simples são definidos explicitamente para ater uma determinada


faixa de valores e um comportamento matemático. Linguagens como C e C++
permitem que o tamanho de um inteiro varie conforme o ambiente de execução.
Em Java isso não acontece. Por causa dos requisitos de portabilidade de Java,
todos os tipos de dados têm uma faixa de valores estritamente definida. Por
exemplo, um int é sempre de 32 bits, independentemente da plataforma de
execução. Isso garante que os programas rodarão em qualquer arquitetura de
máquina.

Embora uma rigorosa especificação do tamanho de um inteiro possa causar


uma pequena perda de performance em alguns ambientes, isso é necessário para
garantir a portabilidade. A seguir, examinaremos cada tipo individualmente.

Tipos Inteiros

Existem quatro tipos de inteiros em Java:

ƒ byte
ƒ short
ƒ int
ƒ long

Todos eles têm sinal, podendo assumir valores positivos e negativos. Ao


contrário de C/C++, Java não tem os tipos sem sinal (unsigned) somente positivos.
Acontece que o conceito de unsigned é usado principalmente para especificar o
comportamento do bit de ordem mais alta, que define o sinal de um int quando
expresso como um número.

A largura de um tipo inteiro deve ser entendida não como a quantidade de


armazenamento que ele consome, mas sim como o comportamento que define
para variáveis e expressões desse tipo. O ambiente run-time de Java tem
liberdade para usar qualquer tamanho que deseje, desde que os tipos se
comportem da forma declarada. Na verdade, pelo menos uma implementação
armazena os tipos byte e short em 32 bits, ao invés de 8 e 16 bits, para melhorar a
performance, porque esse é o tamanho da palavra usada atualmente pela maioria
dos computadores.
A largura e o alcance dos tipos inteiros em Java varia amplamente,
conforme mostrado na tabela:

Tipo de Largura Valor Mínimo Valor Máximo


Inteiro
long 64 - 9.223.372.036.854.755.807
9.223.372.036.854.755.808
int 32 -2.147.483.648 2.147.483.647
short 16 -32.768 32.767
byte 8 -128 127

Tipo Byte

O tipo byte representa o menor dos tipos inteiros de Java. Byte é um tipo
inteiro de 8 bits com sinal que tem faixa de valores entre – 128 a 127. As variáveis
desse tipo são especialmente úteis quando trabalhamos com um fluxo de dados
de uma rede ou de um arquivo. Byte também é prático para trabalhar com dados
binários brutos que podem não ser diretamente compatíveis com os outros tipos
embutidos de Java. As variáveis do tipo byte são declaradas usando-se a palavra
reservada byte. Por exemplo, a seguinte linha declara duas variáveis byte,
chamadas b1 e b2:

byte b1, b2;

Tipo short

O tipo short é um inteiro de 16 bits com sinal. Sua faixa vai de -32.768 a
32.767. É o tipo menos usado em Java, por cusa de uma particularidade: é
definido como tendo o byte mais alto primeiro, o chamado formato big-endian.
Esse tipo aplica-se principalmente a computadores de 16 bits, que estão se
tornando cada vez mais raros. Eis alguns exemplos de declarações de variáveis
short:

short s1;
short shortVar;

Tipo int

O tipo int representa o tipo inteiro mais utilizado em Java. Trata-se de um


inteiro de 32 bits com sinal que tem faixa de valores entre -2.147.483.648 e
2.147.483.647. Entre outros usos, variáveis do tipo int são muito usadas para
controlar loops e indexar arrays.
Sempre que temos uma expressão inteira envolvendo bytes, shorts, ints e
números literais, a expressão inteira é promovida para int antes que o cálculo seja
efetuado. O tipo int é o mais versátil e eficiente e deve ser usado na maioria das
vezes quando queremos contar números para contagem ou indexação de arrays,
ou para fazer matemática de inteiros.

Tipo long

O tipo long representa um tipo inteiro de 64 bits com sinal. Ele é útil nas
situações em que um tipo não é grande o suficiente para conter o valor desejado.
A faixa de valores de long é bastante grande. Isso o torna útil quando há
necessidade de lidar com grandes números inteiros.

Por exemplo, o programa abaixo computa o número de quilômetros que a


luz viaja em um determinado número de dias.

1. import javax.swing.JOptionPane;
2. public class DistLuz
3. {
4. public static void main (String args [ ] )
5. {
6. int velocLuz=300000;
7. long dis=1000, segundos=0, distancia;
8. distancia=velocLuz*segundos;
9. JOptionPane.showMessageDialog(null,"Em"+ " " +dis);
10. JOptionPane.showMessageDialog(null," "+"dias a luz percorre" + " ");
11. JOptionPane.showMessageDialog(null, distancia + " " + " Km ");
12. } // Fim de main ( )
13. } // Fim da classe DistLuz.

Este programa exibe na tela o seguinte resultado:

Em 1.000 dias a luz percorre 25920000000000 km.

É perceptível que esse valor não poderia ser contido em uma variável int.

Tipos com Ponto Flutuante

Os números de ponto flutuante, ou números reais, são usados para avaliar


expressões que requerem precisão fracional. Raiz quadrada e funções
trigonométricas como seno e co-seno são exemplos de cálculos que resultam em
valores cuja precisão requer um tipo com ponto flutuante.

Java implementa o conjunto de tipos e operadores de ponto flutuante do


padrão IEEE-754. Existem duas variedades de tipos de ponto flutuante:
ƒ float → ponto flutuante com precisão simples

ƒ double → ponto flutuante com precisão dupla

Suas larguras e faixas de valores são mostradas a seguir:

Tipo de Ponto Flutuante Largura de Bits Faixa de Valores


double 64 1.7e-308 a 1.7e+308
float 32 3.4e-038 a 3.4e+0,38

Tipo Float

O tipo float especifica um valor de precisão que utiliza 32 bits de armazenamento.


Como tudo na vida, em comparação com o tipo doublé, o float tem um lado
positivo e um negativo:

ƒ A precisão simples é mais veloz em alguns processadores e ocupa a


metade do espaço da precisão dupla...
ƒ ... mas torna-se imprecisa quando os valores se tornam muito grandes ou
muito pequenos.

Variáveis do tipo float são úteis quando precisamos de um componente


fracional, mas sem ter uma alto grau de precisão.

Por exemplo, float pode ser usado para representar reais e centavos. Eis
alguns exemplos de declarações de variáveis float:

float entrada, mensalidade;

Tipo double

A precisão dupla, representada pela palavra-chave double, utiliza 64 bits


para armazenar um valor. Em alguns processadores modernos, otimizados para
cálculos matemáticos de alta velocidade, a precisão dupla chega a ser mais veloz
que a precisão simples.

Em Java, várias funções matemáticas como sin(), cos() e sqrt() retornam


valores double. Quando precisamos manter a precisão ao longo de cálculos
repetitivos, ao trabalhar com números com elevados valores, double é a melhor
opção.

3.14.1 Tipo char


char é o tipo usado em Java para armazenar caracteres. Porém, apesar de
o nome ser o mesmo, os programadores C/C++ precisam ter em mente que um
char em Java não é o mesmo que um char em C ou C++. Em C/C++, um char é,
na verdade, um tipo inteiro com largura de oito bits. Isso não acontece em Java.

Java utiliza Unicode para representar os caracteres. O Unicode define um


conjunto internacional de caracteres, capaz de representar os caracteres de todas
as línguas humanas. Ele reúne dezenas de conjuntos de caracteres, como latino,
grego, arábico, cirílico, hebraico, katakana, hangul e muitos outros. Para
possibilitar isso, são necessários 16 bits.

É por isso que o tipo char de Java tem 16 bits. O alcance é de 0 a 65.536.
char não pode assumir valores negativos.

O conjunto-padrão de caracteres conhecido com ASCII continua assumindo


valores entre 0 a 127, como sempre, e o conjunto estendido de caracteres, o
ISSO-Latin_1, varia de 0 a 255.

Como Java foi criado para permitir que sejam escritos applets para uso em
todo o mundo, faz sentido o uso de Unicode para representar os caracteres. É
claro que o Unicode é um tanto ineficiente para línguas em inglês, português,
espanhol e francês, cujos caracteres podem ser facilmente contidos em 8 bits.
Mas esse é um preço que pagamos para ter portabilidade global. Eis um programa
que demonstra o uso de variáveis char.

1. import javax.swing.JOptionPane;
2. public class TesteChar
3. {
4. public static void main(String[ ] args)
5. {
6. char charl, char2;
7. charl=77;
8. char2=71;
9. JOptionPane.showMessageDialog(null, "Minhas Iniciais:" );
10. JOptionPane.showMessageDialog(null, charl + " " + char2) ;
11. } // Fim de main ( )
12. } // Fim da classe TesteChar.

Este programa exibe n tela a seguinte saída:

Minhas Iniciais: M G

Observe que nas linhas 9 e 10, char1 e char2 recebem respectivamente os


valores 77 e 71, que são valores ASCII (e, neste caso, também Unicode) que
correspondem às letras M e G. Lembre-se de que o conjunto de caracteres ASCII
ocupa os primeiros 127 valores do conjunto de caracteres Unicode. Por esse
motivo, todos os truques que eram usados com caracteres também vão funcionar
em Java.

Embora o tipo char não seja igual a um inteiro, em muitas situações é


possível operar com um char como se fosse inteiro. Por exemplo, podemos somar
dois chars, ou incrementar o valor de uma variável char.

Tipo Boolean

O tipo boolean de Java é usado para conter valores lógicos do tipo false/true
(falso/verdadeiro). Esse é o tipo retornado por todos os operadores relacionais,
como a < b. boolean é também o tipo exigido em todas as expressões
condicionais que governam comandos de controle, como if e for. Eis um programa
que demonstra o tipo boolean:

1. import javax.swing.JOptionPane;
2. public class TesteBoolean
3. {
4. public static void main ( String args [ ] )
5. {
6. boolean bool;
7. bool=false;
8. JOptionPane.showMessageDialog(null, "bool é " + " " + bool);
9. bool=true;
10. JOptionPane.showMessageDialog(null, "bool é " + " " + bool);
11. if (bool) // Um valor boolean controlando o comando if
12. JOptionPane.showMessageDialog(null, "Isso será exibido." );
13. bool=false;
14. if (bool)
15. JOptionPane.showMessageDialog(null, "Isso não será exibido" );
16. // O resultado de um operador
17. // relacional e um valor
18. // boolean
19. JOptionPane.showMessageDialog(null, " 4 > 3 e " + " " + ( 4 > 3 ) ) ;
20. } // Fim de main ( )
21. } // Fim da classe TesteBoolean.

A saída gerada por este programa é a seguinte:

bool é false
bool é true
Isso será exibido
4>3 é true

Vamos examinar TesteBool.java. Nas linhas 8 e 10 podemos ver que, quando um


tipo boolean é exibido com ajuda do método showMessageDialog(), o que aparece
são as palavras true ou false. Na linha 14 vemos que o valor de uma variável
boolean sozinha já é suficiente para controlar o comando if. Não há necessidade
de escrever o comando if desta forma:

If (bool==true) // Desnecessário ! ! !

Na linha 19 vemos que o resultado de um operador relacional, como <, é


um valor boolean. É por isso que a expressão 4 > 3 exibe o valor true. Também na
linha 19 observe que o par de parênteses contém a expressão (4 > 3) é
necessário. Isto acontece porque o operador + tem precedência mais alta que o
operador >.

Operações de Cast em Java

Para resolver certos problemas em programação, é relativamente comum


atribuir um valor de um tipo a uma variável de outro tipo. Se os tipos forem
compatíveis, Java fará a conversão automaticamente. Um exemplo: sempre é
possível atribuir um valor int a uma variável long.

Porém nem todos os tipos são compatíveis, de modo que nem todas as
conversões são implicitamente permitidas. Por exemplo, não existe uma
conversão de doublé para byte.

Para conseguir uma conversão entre tipos compatíveis, usamos o recurso


chamado cast Ele executa uma conversão explícita entre tipos incompatíveis.
Nesta e nas próximas lições examinaremos os dois tipos de conversão:
automática e com o uso de cast.

Quando um dado de um tipo é atribuído a uma variável de outro tipo, ocorre


uma conversão automática de tipo se as duas condições seguintes forem
satisfeitas:

• Os dois tipos forem compatíveis.

• Tipo de destino tiver largura maior que o tipo original.

Quando essas duas condições forem satisfeitas, ocorrerá uma conversão por
alargamento. Por exemplo, o tipo int sempre é grande o suficiente para conter
todos os valores do tipo byte, de modo que não há necessidade de uso de um
cast explícito.

Nas conversões por alargamento, os tipos numéricos, inclusive os tipos


inteiros e de ponto flutuante, são compatíveis entre si. Contudo, os tipos
numéricos não são compatíveis com char ou boolean. E também, char e boolean
não são compatíveis entre si.
Conforme mencionado anteriormente, Java também executa uma
conversão automática de tipo ao armazenar uma constante literal inteira em uma
variável do tipo byte, short ou long.

3.14.2 Como usar Cast Entre Tipos Incompatíveis

As conversões automáticas ajudam muito, mas não atendem a todas as


necessidades de programação.

Por exemplo, o que acontece se precisarmos atribuir um valor double a uma


variável int ? Essa conversão não é feita automaticamente, porque int é menor que
um double. Esse tipo de conversão é conhecido como conversão por
estreitamento, já que estamos explicitamente tornando o valor mais estreito, para
que ele caiba no tipo-alvo.

Para criar uma conversão entre dois tipos incompatíveis, é preciso usar
cast. Um cast é simplesmente uma conversão explícita de tipo. Em nosso exemplo
anterior, de double para int, o cast teria a seguinte forma:

int doubleVar;
int intVar;
//...
intVar= ( int ) doubleVar;

A conversão que ocorre quando um valor de ponto flutuante é atribuído a


um tipo inteiro é diferente. Consiste em um truncamento. Como sabemos, valores
inteiros não têm o componente fracionário. Assim, quando um valor de ponto
flutuante é atribuído a um tipo inteiro, o componente fracionário é perdido.

Por exemplo, se o valor 3.14.16 for atribuído a um inteiro, o valor resultante


será simplesmente 3. A parte fracionária .1416 será truncada. Importante: se o
tamanho da parte inteira do número for grande demais para caber no tipo-alvo
inteiro, então o valor será reduzido usando a operação módulo pelo alcance do
tipo-alvo.