quinta-feira, 3 de setembro de 2009

Promoção tipos Primitivos,cast,Pass by value

Sumário:Cast, Promoção, Pass by Value

Regra básica:
1-
Em Tipos Primitivos Inteiros , int é Default.
2- Em Tipos Primitivos Ponto - Flutuante, double é Default.


Por facilidade trabalharemos nesse tutorial com os valores em decimal, Porem lembre-se que tipos primitivos em java trabalham com bits em si, oque seria:

No caso, o tipo int tem 32 bits, so representei 8 porque antes dele será adicionado somente 0 para chegar em 32 ou seja:
0000 0000 0000 0000 0000 0000 0001 0100, e eu coloquei: 0001 0100



Princípios Básicos de Acontecimento de erros:

A Atribuição de valores de uma expressão a outra pode dar incompatibilidade de dados entre os dados da expressão e os dados armazenados. Para Resolver esse problema, Podemos ou promover(Promotion) os dados da expressão ou converter(cast) os dados da expressão.

Exemplo:

int a = 2;
int b = 5;
byte c = a + b; -> Dará um Erro de compilação.

Ilustrando:


Clique na imagem para ampliar



Como arrumar este problema?

1-
int a = 2;
int b = 5;
int c = a + b; // Temos um int recebendo a soma de int

ou

2-
int a = 2;
int b = 5;
byte c = (byte)(a + b); // Temos um byte recebendo o cast de uma expressão para byte


Promoção:

Em algunas casos, o compilador Promove , a expressão ou o Operando em um tipo Maior(do mesmo tipo da Variavel de atribuição)Isso é referênciado como Promoção, ocorre automaticamente pelo compilador se não houver perda de dados.

O local de Armazenamento em memória, sempre tem o tamanho igual ao tipo Armazenado, Se tenho a Declaração de uma variável Local, ela terá o tamanho do tipo Declarado, ex:

byte minhaVariavel; -> Aqui o espaço de memoria aguenta no máximo 8 bytes


Vamos a um exemplo:

Declaro uma variavel local:

int minhaVariavel = 20;

No mesmo escopo, atribuo o valor da minha variavel a Outra:

float minhaOutraVariavel = minhaVariavel;


Acabou de ocorrer Promoção, de int(Tipo Inteiro) para float(Tipo Ponto- Flutuante), So que o valor da - minhaOutraVariavel - Será 20.0 e não 20, pois agora ela é um Ponto-Flutuante;



Clique na imagem para ampliar





Tipo Casting:
É quando um valor maior é convertido a um menor, ou o resultado de uma expressão é convertido.
Use: (tipo_cast)

Cuidado ao usar cast, a Conversão de dados é um contrato que você faz com o compilador dizendo:
- Olha compilador, eu me garanto pelo oque vier como resultado, eu sei oque estou fazendo.


Exemplo:

int a = 2;
int b = 5;
byte c = (byte)(a + b);

Em bytecode temos:

Code:
0: iconst_2
1: istore_1 //
int a = 2;
2: iconst_5
3: istore_2 //
int b = 5;
4: iload_1 //2
5: iload_2 //5
6: iadd
7: i2b
8: istore_3



Vamos partir do ponto:
byte c = (byte)(a + b) , Teremos isso em memória quando chegar nesse ponto, e no bytecode acima estamos em iadd


Clique na imagem para ampliar

Após a soma de a e b :

Clique na imagem para ampliar


Agora sim vamos para o cast do RESULTADO:


Clique na imagem para ampliar


E finalmente o armazenamento:

Clique na imagem para ampliar, ou seja c = 0000 0111 em decimal o valor 7



Clique na imagem para ampliar


Outro exemplo:

float f = 20.0002F;
int i = (int) f; //int i terá o valor de 20, Pois agora se tornou tipo Inteiro.


Importante:
É sempre bom colocar entre -( ) Parênteses - Toda a Expressão que será convertida:

int x = 10;
int y = 20;
byte c = (byte) (x + y); -> Compilação OK

Sem parênteses:

int x = 10;
int y = 20;
byte c = (byte)x + y; -> Erro de Compilação

Os operadores usam os valores como valor Default, oque ocorre nessa expressão é:
1 - x é convertido para byte
2 - É avaliado o operador(+), então x e y virão Default de Inteiros(int)
3 - Soma-se x + y
4 - Tenta-se Armazenar int em byte, oque não é possível, erro de Compilação.


ATENÇÃO em Tipos Inteiros e Operadores:

Lembre-se e tenha atenção, OPERADORES(*,/,+,-,%) ELEVAM O TIPO DOS OPERANDOS EM int ou em tipos maiores se necessário ou se estiverem na expressão,isso significa que se tivermos 2 Operandos em meio a um operador, Eles são convertidos a int antes mesmo de fazer o operador:

byte a = 2;
byte c = 3;
byte d = a + c; -> Erro de Compilação, a e c serão convertidos a int antes do Operador.

Nesse Exemplo, os Operandos a e c são convertidos para int por causa do Operador(+) depois com o operador(= igual) tenta-se armazenar em um tipo byte(byte b) oque não é possível.

Outro exemplo:

long x = 10 + 24L + 5;

Nesse caso os operadores não podem elevar os inteiros para int, sendo que um deles é long(24 L), sendo assim todos os Operadores são avaliados para valores Maiores ou seja todos viram long.


ATENÇÃO em Pontos Flutuantes:
Toda vez que se declara um valor do tipo float, deve-se especificar o f(ou F) ou fazer cast.

float f = 0.0; -> Erro de compilação, 0.0 é double(Default)

float f = (float) 0.0 -> cast, compilação OK

float f = 0.0f -> cast, compilação OK

float f = 0.0F -> cast, compilação OK


Copia de valores(Pass - by - value):
Java trabalha com cópia de valores, isso significa que nenhum valor é retirado e sim COPIADO:

int x = 2;
int c = x; -> Os bits de 2 são copiados para - int c - e não retirados de - int x-



Curiosidade:

- Quando usamos:

long l = 20;
Isso é possível de ocorrer por causa da Promoção, 20 é do tipo int por Default dos valores Inteiros, long é maior que int, logo Promoção.


Um Exemplo prático:

public class MinhaClasse{



public static voi main(String array[]){
int minhaInt = 10;
byte minhaVariavel = minhaInt;

}
}

Porque isso da erro de Compilação?
Pois estamos tentado armazenar um int em um byte, Esse int ja existe e ja foi armazenado portanto você esta carregando um valor com tamanho em bits já definido.

Vejamos mais a fundo:
O main será um frame em Runtime, então demonstramos Local Variable e Operand Stack do Frame dele.

Você esta tentando fazer isso, Desenhando:


Clique na imagem para ampliar


Oque é totalmente diferente disso:

public class MinhaClasse{



public static voi main(String array[]){
byte minhaVariavel = 10;

}
}

Agora você fez isso:



Clique na imagem para Ampliar


Resultando nisso:


Sendo index 1 da Local Variable a minhaVariavel.Clique na imagem para Ampliar


É hora da Revisão:

- Em Tipos Primitivos, os valores são armazenado em bits
- Em Tipos Primitivos Inteiros, int é Default
- Em tipos Primitivos Ponto-Flutuante, double é Default
- O tipo que estiver antes do (= igual) é o local que vai armazenar oque estiver depois do (= igual),


- Quando o valor que estiver a direita do igual(Operador = ) for menor que o da esquerda do igual(Operador = ) ocorre Promoção



- Quando o valor que estiver a direita do igual(Operador = ) for maior que o da esquerda do igual(Operador = ) deve-se fazer cast

Clique na imagem para ampliar

- Cuidado ao fazer cast, o valor pode perder o sentido, Lembre-se trabalhamos com bits ou seja são "cortados" para encaixar no outro tipo, vejamos:


Clique na imagem para ampliar

- Em cast de expressões use Parênteses - ( ) - NA EXPRESSÃO:

byte a = 2, b = 3;
byte c = (byte) a + b; -> Erro de compilação, por causa da Precedência e Do Operador SOMA(+) que faz com que a e b sejam int

byte a = 2, b = 3;
byte c = (byte) (a + b); -> Compilação OK

- Importanção de variável ja armazenada é totalmente diferente de declarar um novo valor:

int c = 3;
byte d = c; -> erro de compilação

byte d = 3; -> O valor será realmente definido com 8 bits após ser armazenado

- Toda vez que tiver Operadores(+,-,%,*,/) Tome cuidado nos tipos Inteiros pois,Os Operandos são transformados em int ou se necessário em tipos Maiores

- Em tipos Ponto-Flutuantes float, sempre faça cast, com (f ou F) ou (float) pois double é Default

- Java trabalha com Pass-by-value ou seja, O valor é Copiado e não substituido

Bom é só isso, Próximo Post Variáveis de Referência.
Cya Dudes!!!

Nenhum comentário:

Postar um comentário