Atribuições e conversões de Tipos Primitivos em Java
Autor: José Anderson | Publicado: 2012-12-24T10:30:00-02:00

Atribuições de Tipos Primitivos

Em Java (e na maioria das linguagens), utilizamos o sinal de igualdade (=) para fazer atribuições de valores em variáveis. Esse operador é chamado de operador de atribuição, e já o utilizamos para fazer atribuições de valores literais nas lições anteriores.

Você pode atribuir a uma variável primitiva um valor literal, o resultado de uma expressão, o valor contido em outra variável do mesmo tipo ou o resultado de algum método (veremos mais sobre métodos adiante), desde que esses valores sejam do mesmo tipo.

int x = 8; //Atribuição de um literal
int y = x * 3; //Atribuição de uma expressão (variável + literal)
int z = x + y; //Atribuição de uma expressão (variável + variável)

Quando atribuímos valores literais às variáveis dos tipos numéricos inteiros (byte, short, int, long e char), obedecemos as seguintes regras:

Atribuições diretas para byte, char, short, int, desde que os valores não extrapolem os limites numéricos de cada tipo:

byte b = 127;
b = -128;
short s = 32767;
s = -32768;
int i = 2147483647;
i = -2147483648;

No caso do tipo char, é importante saber que, além de atribuirmos caracteres, podemos atribuir valores numéricos inteiros não negativos de 0 a 65535.

char c = 65535;
c = 0;

Sabemos que em Java um valor literal numérico sem ponto flutuante é do tipo int independente da faixa de valores.

Então é importante saber que não seria possível incluir esses valores descritos acima nas variáveis dos tipos byte, char e short devido a esses valores ocuparem 32 bits na memória. Isso não acontece porque, no momento da compilação, esses valores são convertidos implicitamente para os tipos correspondentes.

No caso do long, podemos fazer atribuições diretas de valores inteiros, e quando um valor ultrapassa a faixa de valores tamanho do tipo int, devemos utilizar o sufixo L ou l para indicarmos que esse valor é do tipo long.

long l = 2147483647;
l = 2147483648L;

Quando atribuímos valores literais de ponto flutuante (float e double), obedecemos as seguintes regras:

Atribuições em float necessitam do uso do sufixo f ou F, pois em java todo literal de ponto flutuante é considerado como tipo double. Também é necessário que o literal esteja dentro da faixa de valores do float para evitar erros de compilação.

Atribuições diretas double desde que a faixa de valores não extrapole o tamanho do tipo double.

float f = 12.89899889980f;
double d = 1256893.5;

Quando atribuímos valores em variáveis como resultado de expressões matemáticas, devemos obedecer as seguintes regras:

Para dados numéricos, prevalece o tipo de maior tamanho. Por exemplo:

O cálculo de int com int retorna int.

int multiplicacao = 2147 * 2147; // iqual a 4609609 

O cálculo de int com long retorna long.

long soma = 90 + 50L;

O cálculo de int com float retorna float.

float subtracao = 5 + 58.508f;

O cálculo de long com float retorna float.

float divisao = 10L / 3.0f;

O cálculo de float com double retorna double.

double d = 10f / 3.0;

Verificamos nos códigos citados que a ordem de prioridade é do maior para o menor tipo, ou seja: em cálculos matemáticos, sempre prevalecerá o resultado com o tipo de maior tamanho.


Conversões de tipos primitivos

Muitas vezes precisamos fazer cálculos e guardar o resultado em alguma outra variável para uso posterior, porém o tipo de resultado pode não condizer com o tipo da variável que irá receber esse resultado, seja de outra variável ou resultado de uma expressão matemática.

A conversão de tipos primitivos é a transformação de um tipo para outro. Essas conversões podem ser implícitas ou explícitas.

As conversões implícitas ocorrem quando atribuímos um valor de menor tipo em uma variável de tipo maior. Este tipo de conversão também é conhecido como conversão de ampliação e ocorrerá de forma automática porque um valor de menor tipo sempre caberá em uma variável de maior tipo.

int j = 256;
long h = j; //conversão implícita de um valor int para long

Segundo a especificação da linguagem Java, há 19 conversões implícitas de tipos primitivos: 
byte para short, int, long, float ou double;
short para int, long, float ou double;
char para int, long, float ou double;
int para long, float ou double;
long para float ou double;
float para double.

A conversão de ampliação de um tipo int ou um long de valor para float, ou de um long de valor para double, pode resultar em perda de precisão, ou seja, o resultado pode perder alguns dos bits menos significativos do valor.

A conversão explícita ou de redução ocorre quando precisamos atribuir um valor de tipo maior para uma variável de tipo menor. Nesse caso, precisamos informar diretamente entre parênteses antes da variável, literal ou resultado de uma expressão o tipo de dado que vamos converter.

double pi = 3.141592653589793;
int i = (int) pi; //Conversão explícita de um valor double para o int

Há 22 conversões específicas de redução de tipos primitivos:
short para byte ou char;
char para&nbsp;byte&nbsp;ou short;
int para&nbsp;byte, short ou char;
long de&nbsp;byte, short, char ou int;
float para&nbsp;byte, short, char, int ou long;
double a&nbsp;byte, short, char, int, long, ou float.

Na conversão de redução do tipo primitivo double&nbsp;para float, poderá haver perca de precisão. Um valor do tipo primitivo que ultrapasse o tamanho da faixa de valores que a variável do tipo primitivo está recebendo, o Java simplesmente descarta os bits de ordem superior que não se enquadrarem. Em outras palavras, ele perderá todos os bits à esquerda do valor que você estiver convertendo.