Este capítulo apresenta as características básicas da linguagem, como identificadores, palavras chave, valores literais, tipos de dados e operadores.
Java possui 49 palavras chave, todas elas são escritas em minúsculas:
byte - short - int - long - char - boolean - double - float - public - private - protected - static - abstract - final - strictfp - transient - synchronized - native - void - class - interface - implements - extends - if - else - do - default - switch - case - break - continue - assert - const - goto - throws - throw - new - catch - try - finally - return - this - package - import - instaceof - while - for - volatile - super
Possui três identificadores que são valores literais: null, false, true
Cada uma dessas palavras serão vistas mais adiante no tutorial.
Existem somente oito tipos primitivos em Java, todo o resto é objeto. Estes tipos ficaram na linguagem pela sua velocidade de interação, e por isso não foram transformados em Objetos. Como não são objetos a sua declaração já cria a variável em memória não necessitando de construtores.
Nesta seção os tipos Array e String não são tratados, pois não são considerados tipos primitivos. Ambos são classes e serão tratadas no capítulo sobre classes.
Todos esses tipos possuem uma representação interna em complemento de dois. O valor default para esses atributos é 0 e cada vez que se usar uma constante numérica no código fonte ela será um int a não ser que se coloque a constante ”L”no final do número.
* byte - Tamanho de 8 bits com sinal. Valores de -128 a +127.
* short - Tamanho de 16 bits com sinal. Valores de -32.768 a +32.767.
* int - Tamanho de 32 bits com sinal. Valores de -2.147.483.648 a +2.147.483.647.
* long - Tamanho de 64 bits com sinal. Valores de -9.223.372.036.854.775.808 a +9.223.372.036.854.775.807.
Exemplo:
100L => long
100 => int
0L => long
0 => int
Não existe os tipos unsigned, long int ou short int em Java.
Os pontos flutuantes seguem a representação IEEE 754, sendo que 0.0 é o valor default. No código fonte, tudo o número com decimais será um float a não ser que o caractere ”d” ou ”D” estejam no final do número.
* float - Tamanho de 32 bits com sinal.
Valores de -1.40239846E-45 a +3.40282347E+38 (com nove dígitos significativos de precisão).
* double - Tamanho de 64 bits com sinal.
Valores de -4.94065645841246544E-324 a +1.79769313486231570E+308 (com 18 dígitos significativos de precisão).
Exemplo:
100.0 => float
100.00d => double
0 => float
0f => float
0d => double
O caractere guarda o valor traduzido de um código ASCII. Seu valor default é o código zero, ;
char - Caractere Unicode com tamanho 16 bits sem sinal. Valores possíveis 0 a 65535
O char também pode ser representado por um numero inteiro de 16 bits sem sinal, ou seja, pode-se atribuir à uma variável char o valor 100 ou o valor 65535, pois se está operando com os valores da tabela Unicode que representam caracteres de qualquer idioma.
Tipos boleanos identificam verdadeiro ou falso e podem ser utilizados diretamente em expressões de retorno para testes como if, switch, while e for., porém não podem ser comparados com variáveis ou constantes numéricas como em C.
boolean - Valor indicando true ou false. Tamanho de 8 bit.
Abaixo segue uma lista com os valores padrões de todos os tipos primitivos, sendo que não é necessário inicializar as variáveis com esses valores, a máquina virtual cuidará desse trabalho.
* byte = 0;
* short = 0;
* int = 0;
* long = 0;
* float = 0.0;
* double = 0.0;
* boolean = false;
* char = `u0000';
* Object = null;
Um objeto, como veremos mais adiante, é inicializado com valor null, pois ele necessita que a instância seja criada explicitamente, o que não ocorre em tipos primitivos.
Os identificadores em Java iniciam com uma letra, um sublinhado ”_”ou um sinal de dólar "$" e podem possuir números após o primeiro caractere da palavra. Pela premissa de ser case-sensitive existe uma diferenciação entre letras maiúsculas e minúsculas. Identificadores válidos são:
identificador
meu_Carro
MeuCarro2
_atributo
$bola
_2seg
Identificadores usados para determinar nomes de variáveis, atributos de classe ou de instância, parâmetros e métodos.
O sinal de atribuição em Java é o "=" igual ao "=" do C e ao ":=" do Delphi. Vale deixar gravado que a comparação é feita com "==" como no C. Uma atribuição é feita com a seguinte sintaxe:
<identificador> = <valor > ;
Veja o exemplo:
public class Atribuição {
public static void main(String[] args) {
int x = 1;
int y = 5;
}
}
No exemplo é atribuído as variáveis inteiras x e y os valores 1 e 5 respectivamente.
O valor literal é um valor escrito no código fonte e identificado como de um tipo primitivo.
int x = 1; // literal inteiro
char u = 'a'; // literal char
boolean b = true; // literal boolean
double d = 002.11d; // literal double
Há três maneiras de representar literais numéricos inteiros em Java:
- octal (base 8). Representado com um 0 na frente de cada valor numérico. Exemplo:
int x = 01;
int x = 0931;
int x = 021;
- hexadecimal (base 16). Representado com um 0x na frente de cada valor numérico. Exemplo:
int quinze = 0xF; // 15 (decimal)
int vinte_e_nove = 0x1D; // 29 (decimal)
int vinte_e_nove = 0x1D; // 29 (decimal)
int valor = 0xBAFAFA; // 12253946 (decimal)
int valor = 0XBaFaFa; // 12253946 (decimal)
- decimal (base 10). Representado normalmente como o primeiro exemplo.
Caracteres também possuem representação especial. Todo o caractere se encontra entre aspas simples, porém pode-se atribuir um valor inteiro ao caractere sem precisar de uma conversão explícita. Alguns exemplos são:
char a = 'A'; // letra A
char b = '&'; // caractere &
char c = 'u004D'; // letra M (Unicode)
char d = ' '; // Pula de linha
char e = ' '; // Tab
char f = ' '; // Retorno de carro
char g = 'b'; // Backspace
char h = ''; // FormFeed
char i = ''; // Barra
char j = '''; // Apostrofo
char k = '"'; // Aspas duplas
char l = 65; // char recebe o valor de um int
char m = (char)-1; // fora do intervalo, conversão explícita
char n = (char)100000; // fora do intervalo, conversão explícita
1. Conversão implícita, quando o tamanho de uma variável é maior que o tamanho da variável ou o valor que está sendo atribuído. Exemplo:
int y = 10;
long x = y;
O tamanho de int é menor que o de long, portanto é perfeitamente aceitável.
2. Conversão explícita, quando o tamanho de uma variável é menor que o tamanho da variável ou o valor que está sendo atribuído. Exemplo:
long y = 10L;
int x = (int)y;
O tamanho de long é maior que o de int, portanto necessita indicar uma conversão. Esta indicativa é feita pelo tipo da variável, que irá receber o valor, entre parênteses: (int). Se esta informação não for colocada, ocorreria um erro de compilação indicando tipos incompatíveis. Outra forma é usar as constantes de identificação de tipos para fazer uma conversão explícita, como em: long y = 10L;
Operadores aritméticos são aqueles que efetuam operações aritméticas em um ou mais tipos primitivos. A seguir são apresentados os operadores aritméticos unários, que atuam sobre um único identificador.
Op Nome Uso Descrição
++ Incremento var++ / ++var Retorna e adiciona / adiciona e retorna.
-- Decremento var-- / --var Retorna e subtrai / subtrai e retorna.
- Negativo -var Inverte o sinal da variável
+ Positivo +var Não tem efeito.
Abaixo estão os operadores aritméticos que atuam sobre duas variáveis.
Op Nome Uso Descrição
+ Adição x + y Soma x com y.
- Subtração x - y Subtrai y de x.
* Multiplicação x * y Multiplica x por y.
/ Divisão x / y Divide x por y.
% Resto x % y Resto da divisão de x por y..
Os operadores relacionais e lógicos são utilizados em testes e condições de entrada em um fluxo do programa. Abaixo estão todos eles relacionados.
Op Nome Uso Descrição
> Maior que x >y x maior que y.
>= Maior ou igual a x >= y x maior ou igual a y.
< Menor que x <= y x menor ou igual a y.
== Igual a x == y x igual a y.
!= Diferente de x != y x diferente de y.
! NÃO lógico (NOT) !y contrário de y.
&& E lógico (AND) x && y x e y.
|| OU lógico (OR) x ||y x ou y.
instanceof Verif Instância x instanceof X x é instância da classe X
Os operadores bitwise são aqueles que alteram o valor das variáveis em operações lógicas diretamente no processador, tornando-as muito mais performáticas. Estas operações são geralmente chamadas de ”tratamento por bits” pois são operações que comparam e modificam a variável bit por bit.
Op Nome Uso Descrição
~ Inversão ~ x Inversão dos bits de x.
& E lógico x & y AND bit a bit entre x e y.
| OU lógico x |y OR bit a bit entre x e y.
^ OU excl. lógico x ^y XOR bit a bit entre x e y.
<< Desloc. a esq. x <<y Desloca a esquerda os bits de x, y vezes.
>> Desloc. a dir. x >>y Desloca a direita os bits de x, y vezes.
>>> Desloc. a dir. x >>>y Preenche zero a esquerda de x, y vezes.
Já foi apresentado o operador de atribuição "=". Porém este operador pode funcionar em conjunto com outros operadores reduzindo o tempo de processamento de determinadas chamadas. O operador de atribuição composto junta um operador aritmético ou de bitwise com o operador de atribuição. É sempre utilizado na sintaxe var = var como no exemplo abaixo:
public class OperadorAtribuicaoComposto{
public static void main(String[] args) {
int x = 1;
x += 5;
}
}
Neste exemplo a variável inteira x é inicializada com 1 e na linha seguinte é realizado uma operação composta: A soma e atribuição. Esta instrução é semelhante a esta: x = x + 5;. O resultado em x será 6. Outros exemplos são:
public class OperadorAtribuicaoComposto{
public static void main(String[] args) {
int x = 1; // Atribui 1 a x
x += 5; // Equivalente a x = x + 5; x é igual a 6
x *= 2; // Equivalente a x = x * 2; x é igual a 12
x /= 2; // Equivalente a x = x / 2; X é igual a 6
x -= 3; // Equivalente a x = x - 3; x é igual a 3
x %= 5; // Equivalente a x = x % 5; x é igual a 3
x |= 4; // Equivalente a x = x | 4; x é igual a 7
x ^= 1; // Equivalente a x = x ^ 1; x é igual a 6
x &= 255; // Equivalente a x = x & 255; x é igual a 6
x <<= 2; // Equivalente a x = x << 2; x é igual a 24
x >>= 4; // Equivalente a x = x >> 3; x é igual a 1
x >>>= 7; // Equivalente a x = x >>> 7; x é igual a 0
}
}
Tabela de precedência de operadores em ordem decrescente, ou seja, o que está mais acima, ocorre antes.
Precedência |
|
++ -- + - ! (cast) |
|
* / % |
|
+ - |
|
<< >> >>> |
|
<><= >= instanceof |
|
== != |
|
& |
|
^ |
|
| |
|
&& |
|
|| |
|
?: |
|
= *= /= %= += -= <<= >>= >>>= &= |= |
|
|
Este capítulo apresentará o extremamente necessário para a construção de qualquer sistema em Java. Declaração de variáveis, comandos de decisão, repetição e desvio de fluxo no programa. 4.1 Declaração e Inicialização de Variáveis.
A declaração de variáveis em Java pode ser feita em qualquer local do código fonte desde que esteja dentro de uma classe. Quando a declaração da variável é feita globalmente, ou seja, na estrutura da classe, é dita que a variável é um atributo, caso contrário ela continua sendo chamada de variável. O escopo ou a vida de uma variável em Java dura de acordo com o bloco onde ela foi declarada. A variável é criada no primeiro acesso a ela e destruída após o interpretador sair do bloco de execução ao qual ela pertence.
Em Java a declaração de variáveis é feita pelo tipo e depois um identificador. A declaração muitas vezes é acompanhada pela inicialização a qual acrescenta o sinal de atribuição e um valor literal ou variável.
A declaração de uma variável é feita no formato:
<tipo> <identificador> [= <valor inicial>];
Observando o exemplo 4.1 pode-se identificar várias maneiras de declarar inicializar tipos primitivos e objetos. Na linha 3 existe uma declaração simples, ela está criando uma variável byte e o valor de bt será 0. Na linha 4 há a declaração de três variáveis do tipo short: sht1, sht2 e sht3. Todas as três serão inicializadas com zero. Na linha 5 existe a declaração de um inteiro i e a sua inicialização atribuindo o valor 9 para a variável. Na linha 6 há duas variáveis sendo criadas: f1 e f2, ambas receberão o mesmo valor 98.76. Na última linha existe a declaração de uma variável de tipo complexa String. String é a classe que armazena uma cadeia de caracteres sem tamanho definido em Java. No exemplo, ela está sendo inicializada com a cadeia "TESTE". Exemplo:
public class DeclarandoVariáveis {
int atributo = 9; // Declarando uma variável global => Atributo.
public void main(String[] args) {
byte bt; // Declaração simples
short sht1, sht2, sht3; // Declaração múltipla
int i = 9; // Declaração e inicialização
float f1, f2 = 98.76 // Declaração e inicialização múltipla
String str = "TESTE" // Declaração e criação de um objeto String
}
}
Linguagens de alto nível implementam várias estruturas de controle do fluxo do programa para facilitar o desenvolvimento de programas e promover um melhor estilo de programação. Os comandos de seleção e repetição são mais empíricos do que os comandos tradicionais em linguagem de máquina.
Java possui duas instruções de desvio condicionais mais uma palavra reservada que não deve ser usada. Todas elas existem em várias outras linguagens e plataformas.
O comando if executa um trecho de código apenas uma vez, dependendo de sua condição. A sintaxe segue a sintaxe abaixo.
if ( condição ) {
comandos 1
} else {
comandos 2
}
A condição é uma expressão da linguagem java e pode ser qualquer conjunto de operações que retornem um valor booleano. Ex: (i >= 0) ou (a == 5 && b != 5 ||c == a) O "comandos 1" e "comandos 2" são um conjunto de um ou mais comandos da linguagem Java. No caso de ser apenas um comando o uso de {} não é necessário.
Se a condição for verdadeira o interpretador executará o "comandos 1" caso contrário o bloco "comandos 2" será executado. Exemplo:
public class ExemploIf {
public static void main(String[] args) {
int i = 8;
// If que dirá se o valor do i é igual a 1 ou igual a dois.
if (i % 2)
System.out.println("Oito é divisível por dois");
else
System.out.println("Oito não é divisível por dois");
// Verifica se o nome é Vitor.
String nome = "Vitor";
if (nome.equals("Vitor")) {
System.out.println("Nome é Vitor");
} else {
System.out.println("Nome não é Vitor");
}
}
}
No primeiro if do exemplo é testado se o valor de i é divisível por 2, ou seja, se valor de i é par. Se for divisível, é impresso o texto Oito é divisível por dois, caso contrário é impresso o texto Oito não é divisível por dois na linha de comando.
No segundo exemplo é feito um teste para saber se a variável String nome é igual a Vitor. Em comparação de objetos sempre usa-se o método equals. Se o valor de nome for Vitor é impresso Nome é Vitor, caso contrário é impresso Nome não é Vitor.
O comando switch é o mesmo do C e é semelhante ao case do Delphi. Permite selecionar o bloco de código a ser executado baseado no teste lógico de uma expressão. O switch é a forma evoluída para o if, podendo tratar mais de dois blocos de execução.
Sintaxe:
switch ( <expressão> ) {
case <valor1>:<comandos 1>
[break;]
case <valor2>:<comandos 2>
[break;]
case <valor3>:<comandos 3>
[break;]
case <valor4>:<comandos 4>
[break;]
...
default: <comandos default>
}
O comando switch executa a expressão e compara o valor encontrado com os valores: <valor1>, <valor2>, <valor3>, etc. Quando encontra a igualdade ele executa o bloco de comandos daquele valor. A execução continuará até o final do switch ou até que ele encontre um break;. Exemplos:
public class ExemploSwitch {
public static void main(String[] args) {
int i = 2;
// Switch que irá imprimir na tela o valor 2
switch (i) {
case 1 : System.out.println("Valor de i é 1");
break;
case 2 : System.out.println("Valor de i é 2");
break;
case 3 : System.out.println("Valor de i é 3");
break;
default: System.out.println("Default");
}
// Switch que irá imprimir na tela o valor "Vitor"
String nome = "Vitor";
switch (nome.hashcode()) {
case "Vitor".hashCode() : System.out.println("Valor de nome é Vitor");
break;
case "Paulo".hashCode() : System.out.println("Valor de nome é Paulo");
break;
default: System.out.println("Default");
}
}
}
Não é necessário utilizar as chaves ({}) para delimitar um bloco de comandos, pois o interpretador executará todos eles até encontrar um break ou o switch finalizar.
A única limitação do switch é que a <expressão> deve retornar um valor numérico inteiro, qualquer um de seus quatro tipos primitivos. O switch não funciona com String, float, char e boolean por exemplo. E é por este motivo que no segundo switch do exemplo é utilizado o método hashcode(), que retorna um código inteiro único para cada String diferente.
Há um consenso entre os desenvolvedores de software de que instruções goto devem ser usadas somente para criar estruturas de controle, de seleção ou repetição, caso elas não existam na linguagem trabalhada. E é exatamente por isso que, embora a palavra goto seja uma palavra reservada do Java, ela não pode ser utilizada, o compilador Java acusará erro se encontrá-la no código.
Os especialistas afirmam que o goto polui o código fonte e se não for utilizado adequadamente pode se tornar um problema maior do que o próprio software.
Laços controlam uma repetição de execução de acordo com uma condição imposta. Em Java, assim como tantas outras linguagens, existem três tipos de laço: for, while e do..while.
O comando for cria um laço de repetição no fluxo do programa baseado em três parâmetros:
Sintaxe:
for (<expressão inicial>; <condição>; <incremento>) {
<comandos>
}
Exemplos:
public class ExemploFor {
public static void main(String[] args) {
for (int i=0; i < 10; i++) {
System.out.println("Contador é " + i);
}
for (;;) {
System.out.println("Laço infinito.");
}
}
}
O primeiro for do exemplo acima irá apresentar 10 mensagens indicando o contador de 0 até 9. Quando o valor do inteiro i ser igual a 10 o interpretador java alternará o fluxo para o início do outro for.
No segundo for do exemplo o código entra num laço infinito, ou seja o programa não termina, sequer sairá do laço, já que não existe condição para que tal evento ocorra.
O comando while é utilizada quando não se quer que o corpo do laço seja necessariamente executado. A expressão de comparação é avaliada antes que o laço seja executado, enquanto ela for verdadeira os são repetidos.
Sintaxe:
while (<condição>) {
<comandos>
}
Exemplos:
public class ExemploWhile {
public static void main(String[] args) {
int i=0;
while(i++ < 10) {
System.out.println("Contador é " + i);
}
while(true) {
System.out.println("Laço infinito.");
}
}
}
Assim como nos exemplos com o comando for, o primeiro exemplo imprime contadores de 0 até 9 e o segundo é um laço infinito, pois o resultado da condição sempre será verdadeiro.
O comando do..while é utilizada quando se quer que o corpo do laço seja executado pelo menos uma vez. A expressão de comparação é avaliada depois que o laço foi executado, enquanto ela for verdadeira os são repetidos.
Sintaxe:
do {
<comandos>
} while (<condição>);
Exemplos:
public class ExemploDoWhile {
public static void main(String[] args) {
int i=0;
do {
System.out.println("Contador é " + i);
} while(++i < 10)
do {
System.out.println("Laço infinito.");
} while(true);
}
}
Assim como nos exemplos anteriores, o primeiro exemplo do comando do..while imprime contadores de 0 até 9 e o segundo é um laço infinito, pois o resultado da condição sempre será verdadeiro. Embora a diferença entre os dois comandos while sejam mínimas, cada uma é utilizada em uma determinada ocasião.
É a declaração de desvio usada para sair de um laço antes do normal. O tipo determina para onde é transferido o controle. O break é transfere o controle para o final de uma construção de laço (for, do, while ou switch). O laço vai encerrar independentemente de seu valor de comparação e a declaração após o laço será executada. Exemplo:
int i = 0;
while (true) {
System.out.println(i);
if ( i++ <= 10 )
break;
}
Este exemplo imprime os valores da variável i de 0 até 9.
A declaração continue faz com que a execução do programa volte imediatamente para o início do laço, porém para a próxima interação. O continue faz o interpretador pular para a próxima iteração e obriga-o a testar a condição. Exemplo:
for (int i = -10; i < 10; i++) {
if ( i == 0 )
continue;
System.out.println(i);
}
No exemplo, é impresso os valores de -10 até 9 pulando o número zero.