Conversão entre Tipos de Dados
A linguagem Java possui um sistema de tipos forte, o que exige atenção ao manipular diferentes tipos de primitivos. A ordem de precedência de tamanho dos tipos (do menor para o maior) é:
byte < short < int (ou char) < long < float < double
Existem duas formas principais de conversão:
- Conversão Implícita (Widening): Ocorre automaticamente ao atribuir um tipo menor a um tipo maior, pois não há risco de perda de dados.
- Conversão Explícita (Casting): Necessária ao atribuir um tipo maior a um tipo menor. A sintaxe utiliza o tipo de destino entre parênteses.
Exemplo:int i = (int) 10.5;. É crucial estar atento ao overflow (estouro de faixa) e à perda de precisão, especialmente ao converter de ponto flutuante (doubleoufloat) para inteiros.
Regras Específicas:
- Constantes Literais: Literais inteiros podem ser atribuídos diretamente a variáveis
byte,shortouchar, desde que o valor esteja dentro da faixa válida do tipo de destino. - Promoção Numérica: Quando tipos
byte,shortoucharparticipam de operações aritméticas, eles são automaticamente promovidos paraintantes do cálculo.
Operadores Aritméticos
Os operadores básicos incluem +, -, *, / e % (módulo), além dos operadores de incremento ++ e decremento --.
Considere o exemplo a seguir sobre a promoção de tipos:
byte x = 10;
byte y = 20;
// int resultado = x + y; // Correto, o resultado da soma é promovido para int
// byte z = x + y; // Erro de compilação: tipos incompatíveis
// Literal constante
byte k = 10 + 20; // Não gera erro, pois o compilador calcula o valor em tempo de compilação (constante folding)
Notas sobre Divisão:
- A divisão por zero em números inteiros lança uma
ArithmeticException, encerrando o programa se não to tratada. - Para tipos de ponto flutuante, a divisão por zero resulta em
Infinity(infinito positivo) ou-Infinity(infinito negativo).
Operadores de Incremento e Decremento:
- Quando utilizados isoladamente (ex:
a++), não há diferença entre o prefixo (++a) e o sufixo. - Quando utilizados em expressões:
++aincrementa antes de usar o valor;a++usa o valor e depois incrementa.
Operadores de Atribuição Composta:
Operadores como +=, -=, etc., realizam um cast implícito.
short valor = 5;
valor += 5; // Equivalente a: valor = (short) (valor + 5);
Operadores Relacionais e Lógicos
Operadores relacionais (==, !=, >, <, etc.) sempre retornam um valor booleano (true ou false).
Os operadores lógicos incluem && (E), || (OU), ! (NÃO) e ^ (OU Exculsivo/XOR).
O operador ternário é uma forma concisa de estruturar uma decisão:
int resultado = (condicao) ? valorSeVerdadeiro : valorSeFalso;
Operadores Bitwise e Bit Shift
Esses operadores atuam diretamente nos bits dos inteiros. A distinção entre &, | e ^ sendo lógicos ou bitwise depende do tipo dos operandos: se forem booleanos, são lógicos; se forem inteiros, são bitwise.
| Operador | Descrição |
|---|---|
& |
Bitwise AND (retorna 1 apenas se ambos os bits forem 1) |
| |
Bitwise OR (retorna 1 se ao menos um bit for 1) |
~ |
Bitwise NOT (inverte todos os bits, incluindo o sinal) |
^ |
Bitwise XOR (retorna 1 se os bits forem diferentes) |
<< |
Deslocamento à esquerda (preenche com zeros à direita) |
>> |
Deslocamento à direita (preenche com o bit de sinal) |
>>> |
Deslocamento à direita não assinado (preenche com zero) |
As operações bitwise são realizadas no complemento de dois. É importante notar que tipos byte, short e char são promovidos para int durante o processamento.
Aplicação do XOR para Troca de Variáveis:
A propriedade algébrica do XOR permite trocar valores de duas variáveis sem usar uma temporária explícita.
int alpha = 5;
int beta = 6;
alpha = alpha ^ beta;
beta = beta ^ alpha; // beta agora contém o valor original de alpha
alpha = alpha ^ beta; // alpha agora contém o valor original de beta
System.out.println("alpha: " + alpha + ", beta: " + beta);
Medição de Desempenho
Para medir o tempo de execução de um bloco de código em milissegundos, utiliza-se o método estático currentTimeMillis() da classe System.
long inicio = System.currentTimeMillis();
// Execução do código a ser testado
// ...
long fim = System.currentTimeMillis();
System.out.println("Tempo decorrido: " + (fim - inicio) + "ms");